From 94884821ffc7f58f895f8797c4bff4f8984ac60a Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 30 Sep 2015 02:54:44 +0200 Subject: [PATCH 01/28] Fixed another typo. Closes #222 for reals. --- src/Gtk/Perspex.Cairo/Media/DrawingContext.cs | 2 +- src/Perspex.Controls/Border.cs | 2 +- src/Perspex.Controls/Panel.cs | 2 +- src/Perspex.Controls/Presenters/TextPresenter.cs | 2 +- src/Perspex.Controls/TextBlock.cs | 2 +- src/Perspex.HtmlRenderer/Adapters/GraphicsAdapter.cs | 2 +- src/Perspex.HtmlRenderer/HtmlControl.cs | 10 +++++----- src/Perspex.SceneGraph/Media/IDrawingContext.cs | 2 +- src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs index f7524fad43..6987e5a19d 100644 --- a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs +++ b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs @@ -191,7 +191,7 @@ namespace Perspex.Cairo.Media /// /// The brush. /// The rectangle bounds. - public void FillRectange(Brush brush, Rect rect, float cornerRadius) + public void FillRectangle(Brush brush, Rect rect, float cornerRadius) { using (var b = SetBrush(brush, rect.Size)) { diff --git a/src/Perspex.Controls/Border.cs b/src/Perspex.Controls/Border.cs index 1d8a3524d6..8a70987cb0 100644 --- a/src/Perspex.Controls/Border.cs +++ b/src/Perspex.Controls/Border.cs @@ -93,7 +93,7 @@ namespace Perspex.Controls if (background != null) { - context.FillRectange(background, rect, cornerRadius); + context.FillRectangle(background, rect, cornerRadius); } if (borderBrush != null && borderThickness > 0) diff --git a/src/Perspex.Controls/Panel.cs b/src/Perspex.Controls/Panel.cs index 0da3d2800e..76bac0c51f 100644 --- a/src/Perspex.Controls/Panel.cs +++ b/src/Perspex.Controls/Panel.cs @@ -173,7 +173,7 @@ namespace Perspex.Controls if (background != null) { var renderSize = Bounds.Size; - context.FillRectange(background, new Rect(renderSize)); + context.FillRectangle(background, new Rect(renderSize)); } base.Render(context); diff --git a/src/Perspex.Controls/Presenters/TextPresenter.cs b/src/Perspex.Controls/Presenters/TextPresenter.cs index 9679ba78a1..1e6068fd7d 100644 --- a/src/Perspex.Controls/Presenters/TextPresenter.cs +++ b/src/Perspex.Controls/Presenters/TextPresenter.cs @@ -84,7 +84,7 @@ namespace Perspex.Controls.Presenters foreach (var rect in rects) { - context.FillRectange(brush, rect); + context.FillRectangle(brush, rect); } } diff --git a/src/Perspex.Controls/TextBlock.cs b/src/Perspex.Controls/TextBlock.cs index 607754dcb2..cf407e3f41 100644 --- a/src/Perspex.Controls/TextBlock.cs +++ b/src/Perspex.Controls/TextBlock.cs @@ -220,7 +220,7 @@ namespace Perspex.Controls if (background != null) { - context.FillRectange(background, new Rect(Bounds.Size)); + context.FillRectangle(background, new Rect(Bounds.Size)); } FormattedText.Constraint = Bounds.Size; diff --git a/src/Perspex.HtmlRenderer/Adapters/GraphicsAdapter.cs b/src/Perspex.HtmlRenderer/Adapters/GraphicsAdapter.cs index d54e8878f9..8b52a1b573 100644 --- a/src/Perspex.HtmlRenderer/Adapters/GraphicsAdapter.cs +++ b/src/Perspex.HtmlRenderer/Adapters/GraphicsAdapter.cs @@ -249,7 +249,7 @@ namespace TheArtOfDev.HtmlRenderer.Perspex.Adapters public override void DrawRectangle(RBrush brush, double x, double y, double width, double height) { - _g.FillRectange(((BrushAdapter) brush).Brush, new Rect(x, y, width, height)); + _g.FillRectangle(((BrushAdapter) brush).Brush, new Rect(x, y, width, height)); } public override void DrawImage(RImage image, RRect destRect, RRect srcRect) diff --git a/src/Perspex.HtmlRenderer/HtmlControl.cs b/src/Perspex.HtmlRenderer/HtmlControl.cs index 55037f9a2f..b720b17bc0 100644 --- a/src/Perspex.HtmlRenderer/HtmlControl.cs +++ b/src/Perspex.HtmlRenderer/HtmlControl.cs @@ -329,19 +329,19 @@ namespace Perspex.Controls.Html public override void Render(IDrawingContext context) { - context.FillRectange(Background, new Rect(RenderSize)); + context.FillRectangle(Background, new Rect(RenderSize)); if (BorderThickness != new Thickness(0) && BorderBrush != null) { var brush = new SolidColorBrush(Colors.Black); if (BorderThickness.Top > 0) - context.FillRectange(brush, new Rect(0, 0, RenderSize.Width, BorderThickness.Top)); + context.FillRectangle(brush, new Rect(0, 0, RenderSize.Width, BorderThickness.Top)); if (BorderThickness.Bottom > 0) - context.FillRectange(brush, new Rect(0, RenderSize.Height - BorderThickness.Bottom, RenderSize.Width, BorderThickness.Bottom)); + context.FillRectangle(brush, new Rect(0, RenderSize.Height - BorderThickness.Bottom, RenderSize.Width, BorderThickness.Bottom)); if (BorderThickness.Left > 0) - context.FillRectange(brush, new Rect(0, 0, BorderThickness.Left, RenderSize.Height)); + context.FillRectangle(brush, new Rect(0, 0, BorderThickness.Left, RenderSize.Height)); if (BorderThickness.Right > 0) - context.FillRectange(brush, new Rect(RenderSize.Width - BorderThickness.Right, 0, BorderThickness.Right, RenderSize.Height)); + context.FillRectangle(brush, new Rect(RenderSize.Width - BorderThickness.Right, 0, BorderThickness.Right, RenderSize.Height)); } var htmlWidth = HtmlWidth(RenderSize); diff --git a/src/Perspex.SceneGraph/Media/IDrawingContext.cs b/src/Perspex.SceneGraph/Media/IDrawingContext.cs index 18fff1d243..92d1fc4e98 100644 --- a/src/Perspex.SceneGraph/Media/IDrawingContext.cs +++ b/src/Perspex.SceneGraph/Media/IDrawingContext.cs @@ -63,7 +63,7 @@ namespace Perspex.Media /// The brush. /// The rectangle bounds. /// The corner radius. - void FillRectange(Brush brush, Rect rect, float cornerRadius = 0.0f); + void FillRectangle(Brush brush, Rect rect, float cornerRadius = 0.0f); /// /// Pushes a clip rectange. diff --git a/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs b/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs index dc6e84d61a..039f6c30e0 100644 --- a/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs +++ b/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs @@ -199,7 +199,7 @@ namespace Perspex.Direct2D1.Media /// The brush. /// The rectangle bounds. /// The corner radius. - public void FillRectange(Perspex.Media.Brush brush, Rect rect, float cornerRadius) + public void FillRectangle(Perspex.Media.Brush brush, Rect rect, float cornerRadius) { using (var b = CreateBrush(brush, rect.Size)) { From 2152300be562ce1dda592367fdbbcda35771d379 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 10:48:34 +0300 Subject: [PATCH 02/28] Fixed AddOwner call for HotKeyProperty --- src/Perspex.Controls/MenuItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Perspex.Controls/MenuItem.cs b/src/Perspex.Controls/MenuItem.cs index 0acc7ae20f..5a7eef3b28 100644 --- a/src/Perspex.Controls/MenuItem.cs +++ b/src/Perspex.Controls/MenuItem.cs @@ -29,7 +29,7 @@ namespace Perspex.Controls Button.CommandProperty.AddOwner(); public static readonly PerspexProperty HotKeyProperty = - HotKeyManager.HotKeyProperty.AddOwner /// The platform-specific handle. /// A surface wrapped in an . - protected override IDrawingContext CreateDrawingContext(IPlatformHandle handle) + public IDrawingContext CreateDrawingContext(IPlatformHandle handle) { switch (handle.HandleDescriptor) { @@ -68,11 +68,8 @@ namespace Perspex.Cairo handle.HandleDescriptor)); } } - - [DllImport("user32.dll")] - private static extern IntPtr GetDC(IntPtr hwnd); - - public override void Dispose() + + public void Dispose() { if (_surface != null) _surface.Dispose(); diff --git a/src/Perspex.SceneGraph/Platform/IRenderer.cs b/src/Perspex.SceneGraph/Platform/IRenderer.cs index e1e0f31e21..a19593406b 100644 --- a/src/Perspex.SceneGraph/Platform/IRenderer.cs +++ b/src/Perspex.SceneGraph/Platform/IRenderer.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; +using Perspex.Media; namespace Perspex.Platform { @@ -17,16 +18,11 @@ namespace Perspex.Platform public interface IRenderer : IDisposable { /// - /// Gets the number of times has been called. + /// Creates an for a rendering session. /// - int RenderCount { get; } - - /// - /// Renders the specified visual. - /// - /// The visual to render. - /// An optional platform-specific handle. - void Render(IVisual visual, IPlatformHandle handle); + /// The handle to use to create the context. + /// An . + IDrawingContext CreateDrawingContext(IPlatformHandle target); /// /// Resizes the rendered viewport. diff --git a/src/Perspex.SceneGraph/Rendering/RendererBase.cs b/src/Perspex.SceneGraph/Rendering/RendererBase.cs index 26e74dc6ad..4f9440eb4d 100644 --- a/src/Perspex.SceneGraph/Rendering/RendererBase.cs +++ b/src/Perspex.SceneGraph/Rendering/RendererBase.cs @@ -14,61 +14,74 @@ namespace Perspex.Rendering /// /// This class provides implements the platform-independent parts of . /// - public abstract class RendererBase : IRenderer + public static class RendererMixin { /// - /// Gets the number of times has been called. + /// Renders the specified visual. /// - public int RenderCount + /// IRenderer instance + /// The visual to render. + /// An optional platform-specific handle. + public static void Render(this IRenderer renderer, IVisual visual, IPlatformHandle target) { - get; - private set; + using (var ctx = renderer.CreateDrawingContext(target)) + ctx.Render(visual); } - public abstract void Dispose(); - /// /// Renders the specified visual. /// + /// IRenderer instance + /// An optional platform-specific handle. /// The visual to render. - /// An optional platform-specific handle. - public virtual void Render(IVisual visual, IPlatformHandle handle) + /// The current translation. + /// The current transform. + public static void Render(this IRenderer renderer, IVisual visual, IPlatformHandle target, Matrix translation, Matrix transform) { - Render(visual, handle, Matrix.Identity); - ++RenderCount; + using (var ctx = renderer.CreateDrawingContext(target)) + ctx.Render(visual, translation, transform); } /// /// Renders the specified visual with the specified transform and clip. /// + /// IRenderer instance + /// An optional platform-specific handle. /// The visual to render. - /// An optional platform-specific handle. /// The transform. /// An optional clip rectangle. - public virtual void Render(IVisual visual, IPlatformHandle handle, Matrix transform, Rect? clip = null) + public static void Render(this IRenderer renderer, IVisual visual, IPlatformHandle target, Matrix transform, Rect? clip = null) { - using (var context = CreateDrawingContext(handle)) - using (clip.HasValue ? context.PushClip(clip.Value) : null) - { - Render(visual, context, Matrix.Identity, transform); - } + using (var context = renderer.CreateDrawingContext(target)) + context.Render(visual, transform, clip); } /// - /// Resizes the rendered viewport. + /// Renders the specified visual. /// - /// The new width. - /// The new height. - public abstract void Resize(int width, int height); + /// The visual to render. + /// + /// The drawing context. + public static void Render(this IDrawingContext context, IVisual visual) + { + context.Render(visual, Matrix.Identity); + } /// - /// When overriden by a derived class creates an for a - /// rendering session. + /// Renders the specified visual with the specified transform and clip. /// - /// The handle to use to create the context. - /// An . - protected abstract IDrawingContext CreateDrawingContext(IPlatformHandle handle); - + /// The visual to render. + /// The drawing context. + /// The transform. + /// An optional clip rectangle. + public static void Render(this IDrawingContext context, IVisual visual, Matrix transform, Rect? clip = null) + { + using (clip.HasValue ? context.PushClip(clip.Value) : null) + { + context.Render(visual, Matrix.Identity, transform); + } + } + /// /// Renders the specified visual. /// @@ -76,7 +89,7 @@ namespace Perspex.Rendering /// The drawing context. /// The current translation. /// The current transform. - protected virtual void Render(IVisual visual, IDrawingContext context, Matrix translation, Matrix transform) + public static void Render(this IDrawingContext context, IVisual visual, Matrix translation, Matrix transform) { var opacity = visual.Opacity; @@ -108,7 +121,7 @@ namespace Perspex.Rendering foreach (var child in visual.VisualChildren.OrderBy(x => x.ZIndex)) { - Render(child, context, translation, transform); + context.Render(child, translation, transform); } } } diff --git a/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs b/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs index 51f7a71cca..16cda058ce 100644 --- a/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs +++ b/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs @@ -3,6 +3,7 @@ using System; using Perspex.Platform; +using Perspex.Rendering; using SharpDX.Direct2D1; using SharpDX.WIC; diff --git a/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs b/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs index bc049e7ca3..0acb5e07dc 100644 --- a/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs +++ b/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs @@ -4,6 +4,7 @@ using System; using Perspex.Layout; using Perspex.Media; +using Perspex.Rendering; using SharpDX.Direct2D1; namespace Perspex.Direct2D1.Media diff --git a/src/Windows/Perspex.Direct2D1/Renderer.cs b/src/Windows/Perspex.Direct2D1/Renderer.cs index b112dfea65..607270ed69 100644 --- a/src/Windows/Perspex.Direct2D1/Renderer.cs +++ b/src/Windows/Perspex.Direct2D1/Renderer.cs @@ -12,7 +12,7 @@ using DwFactory = SharpDX.DirectWrite.Factory; namespace Perspex.Direct2D1 { - public class Renderer : RendererBase + public class Renderer : IRenderer { /// /// The render target. @@ -77,7 +77,7 @@ namespace Perspex.Direct2D1 /// /// The new width. /// The new height. - public override void Resize(int width, int height) + public void Resize(int width, int height) { WindowRenderTarget window = _renderTarget as WindowRenderTarget; @@ -96,12 +96,12 @@ namespace Perspex.Direct2D1 /// /// The platform handle. Unused. /// An . - protected override IDrawingContext CreateDrawingContext(IPlatformHandle handle) + public IDrawingContext CreateDrawingContext(IPlatformHandle handle) { return new DrawingContext(_renderTarget, DirectWriteFactory); } - public override void Dispose() + public void Dispose() { _renderTarget.Dispose(); } From c8e617231ccf8ec04c00d73caa94aa725d8073bb Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 14:42:43 +0300 Subject: [PATCH 06/28] Moved render-related code from TopLevel to a separate class (needed for wm stuff) --- src/Gtk/Perspex.Cairo/CairoPlatform.cs | 4 +- .../Media/Imaging/RenderTargetBitmapImpl.cs | 8 +-- src/Gtk/Perspex.Cairo/Media/TileBrushes.cs | 2 +- src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj | 2 +- .../{Renderer.cs => Viewport.cs} | 8 +-- src/Perspex.Application/Application.cs | 2 +- src/Perspex.Controls/Perspex.Controls.csproj | 1 + .../Platform/ITopLevelRenderer.cs | 62 +++++++++++++++++++ src/Perspex.Controls/TopLevel.cs | 49 +++------------ .../Perspex.SceneGraph.csproj | 6 +- .../Platform/IPlatformRenderInterface.cs | 4 +- .../{IRenderer.cs => IRenderingViewport.cs} | 2 +- ...enderManager.cs => IRenderQueueManager.cs} | 4 +- .../Rendering/IRenderRoot.cs | 7 +-- ...RenderManager.cs => RenderQueueManager.cs} | 2 +- .../Rendering/RendererBase.cs | 20 +++--- src/Perspex.SceneGraph/Visual.cs | 6 +- .../Perspex.Direct2D1/Direct2D1Platform.cs | 4 +- .../Media/Imaging/RenderTargetBitmapImpl.cs | 4 +- .../Media/VisualBrushImpl.cs | 2 +- .../Perspex.Direct2D1.csproj | 2 +- .../{Renderer.cs => Viewport.cs} | 10 +-- .../ControlTests.cs | 4 +- tests/Perspex.Controls.UnitTests/TestRoot.cs | 4 +- .../TopLevelTests.cs | 6 +- .../FullLayoutTests.cs | 4 +- .../Perspex.SceneGraph.UnitTests/TestRoot.cs | 4 +- 27 files changed, 130 insertions(+), 103 deletions(-) rename src/Gtk/Perspex.Cairo/{Renderer.cs => Viewport.cs} (90%) create mode 100644 src/Perspex.Controls/Platform/ITopLevelRenderer.cs rename src/Perspex.SceneGraph/Platform/{IRenderer.cs => IRenderingViewport.cs} (95%) rename src/Perspex.SceneGraph/Rendering/{IRenderManager.cs => IRenderQueueManager.cs} (88%) rename src/Perspex.SceneGraph/Rendering/{RenderManager.cs => RenderQueueManager.cs} (96%) rename src/Windows/Perspex.Direct2D1/{Renderer.cs => Viewport.cs} (91%) diff --git a/src/Gtk/Perspex.Cairo/CairoPlatform.cs b/src/Gtk/Perspex.Cairo/CairoPlatform.cs index 55da932a59..7d4b5421ee 100644 --- a/src/Gtk/Perspex.Cairo/CairoPlatform.cs +++ b/src/Gtk/Perspex.Cairo/CairoPlatform.cs @@ -36,9 +36,9 @@ namespace Perspex.Cairo return new FormattedTextImpl(s_pangoContext, text, fontFamily, fontSize, fontStyle, textAlignment, fontWeight); } - public IRenderer CreateRenderer(IPlatformHandle handle, double width, double height) + public IRenderingViewport CreateRenderer(IPlatformHandle handle, double width, double height) { - return new Renderer(handle, width, height); + return new Viewport(handle, width, height); } public IRenderTargetBitmapImpl CreateRenderTargetBitmap(int width, int height) diff --git a/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs b/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs index e35780773a..a35c037875 100644 --- a/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs +++ b/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs @@ -14,7 +14,7 @@ namespace Perspex.Cairo.Media.Imaging public RenderTargetBitmapImpl(Cairo.ImageSurface surface) { Surface = surface; - renderer = new Renderer(Surface); + viewport = new Viewport(Surface); } public int PixelWidth => Surface.Width; @@ -23,7 +23,7 @@ namespace Perspex.Cairo.Media.Imaging public void Dispose() { - renderer.Dispose(); + viewport.Dispose(); } public Cairo.ImageSurface Surface @@ -31,10 +31,10 @@ namespace Perspex.Cairo.Media.Imaging get; } - private Renderer renderer; + private Viewport viewport; public void Render(IVisual visual) { - renderer.Render(visual, new PlatformHandle(IntPtr.Zero, "RTB")); + viewport.Render(visual, new PlatformHandle(IntPtr.Zero, "RTB")); } public void Save(string fileName) diff --git a/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs b/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs index 761efc2220..0a4c20246f 100644 --- a/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs +++ b/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs @@ -111,7 +111,7 @@ namespace Perspex.Cairo.Media scale, translate, out drawRect); - var renderer = new Renderer(intermediate); + var renderer = new Viewport(intermediate); context.Rectangle(drawRect.ToCairo()); context.Clip(); diff --git a/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj b/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj index e389fac5b2..3f5d54a26a 100644 --- a/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj +++ b/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj @@ -61,7 +61,7 @@ - + diff --git a/src/Gtk/Perspex.Cairo/Renderer.cs b/src/Gtk/Perspex.Cairo/Viewport.cs similarity index 90% rename from src/Gtk/Perspex.Cairo/Renderer.cs rename to src/Gtk/Perspex.Cairo/Viewport.cs index a99da669f7..2191611f15 100644 --- a/src/Gtk/Perspex.Cairo/Renderer.cs +++ b/src/Gtk/Perspex.Cairo/Viewport.cs @@ -15,22 +15,22 @@ namespace Perspex.Cairo /// /// A cairo renderer. /// - public class Renderer : IRenderer + public class Viewport : IRenderingViewport { private readonly Surface _surface; private Gdk.Window _window; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The window handle. /// The width of the window. /// The height of the window. - public Renderer(IPlatformHandle handle, double width, double height) + public Viewport(IPlatformHandle handle, double width, double height) { } - public Renderer(ImageSurface surface) + public Viewport(ImageSurface surface) { _surface = surface; } diff --git a/src/Perspex.Application/Application.cs b/src/Perspex.Application/Application.cs index f0a3c1a8ee..88f3a23ffe 100644 --- a/src/Perspex.Application/Application.cs +++ b/src/Perspex.Application/Application.cs @@ -168,7 +168,7 @@ namespace Perspex .Bind().ToTransient() .Bind().ToConstant(_styler) .Bind().ToTransient() - .Bind().ToTransient(); + .Bind().ToTransient(); } /// diff --git a/src/Perspex.Controls/Perspex.Controls.csproj b/src/Perspex.Controls/Perspex.Controls.csproj index 12a8f6f7e6..f29b366032 100644 --- a/src/Perspex.Controls/Perspex.Controls.csproj +++ b/src/Perspex.Controls/Perspex.Controls.csproj @@ -43,6 +43,7 @@ + diff --git a/src/Perspex.Controls/Platform/ITopLevelRenderer.cs b/src/Perspex.Controls/Platform/ITopLevelRenderer.cs new file mode 100644 index 0000000000..74afcceeb8 --- /dev/null +++ b/src/Perspex.Controls/Platform/ITopLevelRenderer.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Perspex.Platform; +using Perspex.Rendering; + +namespace Perspex.Controls.Platform +{ + public interface ITopLevelRenderer + { + void Attach(TopLevel topLevel); + } + + + class DefaultTopLevelRenderer : ITopLevelRenderer + { + + public void Attach(TopLevel topLevel) + { + var resources = new List(); + var initialClientSize = topLevel.PlatformImpl.ClientSize; + + + var queueManager = ((IRenderRoot)topLevel).RenderQueueManager; + + if (queueManager == null) + return; + + var platformRender = PerspexLocator.Current.GetService(); + if(platformRender == null) + return; + + var viewport = platformRender + .CreateRenderer(topLevel.PlatformImpl.Handle, initialClientSize.Width, initialClientSize.Height); + resources.Add(viewport); + + + resources.Add(topLevel.GetObservable(TopLevel.ClientSizeProperty).Subscribe(clientSize => + { + viewport.Resize((int) clientSize.Width, (int) clientSize.Height); + })); + resources.Add(queueManager.RenderNeeded.Subscribe(_ + => topLevel.PlatformImpl.Invalidate(new Rect(topLevel.ClientSize)))); + + topLevel.PlatformImpl.Paint = (rect, handle) => + { + viewport.Render(topLevel, handle); + queueManager.RenderFinished(); + }; + + topLevel.Closed += delegate + { + foreach (var disposable in resources) + disposable.Dispose(); + resources.Clear(); + }; + + } + } +} diff --git a/src/Perspex.Controls/TopLevel.cs b/src/Perspex.Controls/TopLevel.cs index 5936e08404..a34d7a1ad0 100644 --- a/src/Perspex.Controls/TopLevel.cs +++ b/src/Perspex.Controls/TopLevel.cs @@ -4,6 +4,7 @@ using System; using System.Reactive.Disposables; using System.Reactive.Linq; +using Perspex.Controls.Platform; using Perspex.Controls.Primitives; using Perspex.Input; using Perspex.Input.Raw; @@ -43,8 +44,8 @@ namespace Perspex.Controls public static readonly PerspexProperty PointerOverElementProperty = PerspexProperty.Register(nameof(IInputRoot.PointerOverElement)); - private readonly IRenderManager _renderManager; - private readonly IRenderer _renderer; + private readonly IRenderQueueManager _renderQueueManager; + private readonly IRenderingViewport _viewport; private readonly IInputManager _inputManager; private readonly IAccessKeyHandler _accessKeyHandler; private readonly IKeyboardNavigationHandler _keyboardNavigationHandler; @@ -92,21 +93,21 @@ namespace Perspex.Controls _inputManager = TryGetService(dependencyResolver); _keyboardNavigationHandler = TryGetService(dependencyResolver); LayoutManager = TryGetService(dependencyResolver); - _renderManager = TryGetService(dependencyResolver); + _renderQueueManager = TryGetService(dependencyResolver); + (TryGetService(dependencyResolver) ?? new DefaultTopLevelRenderer()).Attach(this); PlatformImpl.SetInputRoot(this); PlatformImpl.Activated = HandleActivated; PlatformImpl.Deactivated = HandleDeactivated; PlatformImpl.Closed = HandleClosed; PlatformImpl.Input = HandleInput; - PlatformImpl.Paint = HandlePaint; PlatformImpl.Resized = HandleResized; Size clientSize = ClientSize = PlatformImpl.ClientSize; if (renderInterface != null) { - _renderer = renderInterface.CreateRenderer(PlatformImpl.Handle, clientSize.Width, clientSize.Height); + _viewport = renderInterface.CreateRenderer(PlatformImpl.Handle, clientSize.Width, clientSize.Height); } if (LayoutManager != null) @@ -116,11 +117,6 @@ namespace Perspex.Controls LayoutManager.LayoutCompleted.Subscribe(_ => HandleLayoutCompleted()); } - if (_renderManager != null) - { - _renderManager.RenderNeeded.Subscribe(_ => HandleRenderNeeded()); - } - if (_keyboardNavigationHandler != null) { _keyboardNavigationHandler.SetOwner(this); @@ -188,16 +184,11 @@ namespace Perspex.Controls { get; } - - /// - /// Gets the window renderer. - /// - IRenderer IRenderRoot.Renderer => _renderer; - + /// /// Gets the window render manager. /// - IRenderManager IRenderRoot.RenderManager => _renderManager; + IRenderQueueManager IRenderRoot.RenderQueueManager => _renderQueueManager; /// /// Gets the access key handler for the window. @@ -297,7 +288,6 @@ namespace Perspex.Controls } ClientSize = clientSize; - _renderer.Resize((int)clientSize.Width, (int)clientSize.Height); LayoutManager.ExecuteLayoutPass(); PlatformImpl.Invalidate(new Rect(clientSize)); } @@ -389,28 +379,7 @@ namespace Perspex.Controls /// private void HandleLayoutCompleted() { - _renderManager?.InvalidateRender(this); - } - - /// - /// Handles a render request from . - /// - private void HandleRenderNeeded() - { - Dispatcher.UIThread.InvokeAsync( - () => PlatformImpl.Invalidate(new Rect(ClientSize)), - DispatcherPriority.Render); - } - - /// - /// Handles a paint request from . - /// - /// The rectangle to paint. - /// An optional platform-specific handle. - private void HandlePaint(Rect rect, IPlatformHandle handle) - { - _renderer.Render(this, handle); - _renderManager.RenderFinished(); + _renderQueueManager?.InvalidateRender(this); } } } diff --git a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj index 4b8c5c3778..dafed3ddd9 100644 --- a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj +++ b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj @@ -105,7 +105,7 @@ - + @@ -114,9 +114,9 @@ - + - + diff --git a/src/Perspex.SceneGraph/Platform/IPlatformRenderInterface.cs b/src/Perspex.SceneGraph/Platform/IPlatformRenderInterface.cs index ca40ec8137..9adf05e2e4 100644 --- a/src/Perspex.SceneGraph/Platform/IPlatformRenderInterface.cs +++ b/src/Perspex.SceneGraph/Platform/IPlatformRenderInterface.cs @@ -49,8 +49,8 @@ namespace Perspex.Platform /// The platform handle for the renderer. /// The initial width of the render. /// The initial height of the render. - /// An . - IRenderer CreateRenderer(IPlatformHandle handle, double width, double height); + /// An . + IRenderingViewport CreateRenderer(IPlatformHandle handle, double width, double height); /// /// Creates a render target bitmap implementation. diff --git a/src/Perspex.SceneGraph/Platform/IRenderer.cs b/src/Perspex.SceneGraph/Platform/IRenderingViewport.cs similarity index 95% rename from src/Perspex.SceneGraph/Platform/IRenderer.cs rename to src/Perspex.SceneGraph/Platform/IRenderingViewport.cs index a19593406b..ef9a8452e7 100644 --- a/src/Perspex.SceneGraph/Platform/IRenderer.cs +++ b/src/Perspex.SceneGraph/Platform/IRenderingViewport.cs @@ -15,7 +15,7 @@ namespace Perspex.Platform /// as RenderBase has a default implementation for the non-platform specific parts of a /// renderer. /// - public interface IRenderer : IDisposable + public interface IRenderingViewport : IDisposable { /// /// Creates an for a rendering session. diff --git a/src/Perspex.SceneGraph/Rendering/IRenderManager.cs b/src/Perspex.SceneGraph/Rendering/IRenderQueueManager.cs similarity index 88% rename from src/Perspex.SceneGraph/Rendering/IRenderManager.cs rename to src/Perspex.SceneGraph/Rendering/IRenderQueueManager.cs index cb03a8a19a..a583bcbc85 100644 --- a/src/Perspex.SceneGraph/Rendering/IRenderManager.cs +++ b/src/Perspex.SceneGraph/Rendering/IRenderQueueManager.cs @@ -7,9 +7,9 @@ using System.Reactive; namespace Perspex.Rendering { /// - /// Defines the interface for a . + /// Defines the interface for a . /// - public interface IRenderManager + public interface IRenderQueueManager { /// /// Gets an observable that is fired whenever a render is required. diff --git a/src/Perspex.SceneGraph/Rendering/IRenderRoot.cs b/src/Perspex.SceneGraph/Rendering/IRenderRoot.cs index a6f5846f75..406eedbc3b 100644 --- a/src/Perspex.SceneGraph/Rendering/IRenderRoot.cs +++ b/src/Perspex.SceneGraph/Rendering/IRenderRoot.cs @@ -10,15 +10,10 @@ namespace Perspex.Rendering /// public interface IRenderRoot { - /// - /// Gets the renderer for the tree. - /// - IRenderer Renderer { get; } - /// /// Gets the render manager which schedules renders. /// - IRenderManager RenderManager { get; } + IRenderQueueManager RenderQueueManager { get; } /// /// Translates a point to screen co-ordinates. diff --git a/src/Perspex.SceneGraph/Rendering/RenderManager.cs b/src/Perspex.SceneGraph/Rendering/RenderQueueManager.cs similarity index 96% rename from src/Perspex.SceneGraph/Rendering/RenderManager.cs rename to src/Perspex.SceneGraph/Rendering/RenderQueueManager.cs index 8f89c6d31f..514bb547a6 100644 --- a/src/Perspex.SceneGraph/Rendering/RenderManager.cs +++ b/src/Perspex.SceneGraph/Rendering/RenderQueueManager.cs @@ -10,7 +10,7 @@ namespace Perspex.Rendering /// /// Schedules the rendering of a tree. /// - public class RenderManager : IRenderManager + public class RenderQueueManager : IRenderQueueManager { private readonly Subject _renderNeeded = new Subject(); diff --git a/src/Perspex.SceneGraph/Rendering/RendererBase.cs b/src/Perspex.SceneGraph/Rendering/RendererBase.cs index 4f9440eb4d..e0a886f66f 100644 --- a/src/Perspex.SceneGraph/Rendering/RendererBase.cs +++ b/src/Perspex.SceneGraph/Rendering/RendererBase.cs @@ -12,47 +12,47 @@ namespace Perspex.Rendering /// Base class for standard renderers. /// /// - /// This class provides implements the platform-independent parts of . + /// This class provides implements the platform-independent parts of . /// public static class RendererMixin { /// /// Renders the specified visual. /// - /// IRenderer instance + /// IRenderer instance /// The visual to render. /// An optional platform-specific handle. - public static void Render(this IRenderer renderer, IVisual visual, IPlatformHandle target) + public static void Render(this IRenderingViewport viewport, IVisual visual, IPlatformHandle target) { - using (var ctx = renderer.CreateDrawingContext(target)) + using (var ctx = viewport.CreateDrawingContext(target)) ctx.Render(visual); } /// /// Renders the specified visual. /// - /// IRenderer instance + /// IRenderer instance /// An optional platform-specific handle. /// The visual to render. /// The current translation. /// The current transform. - public static void Render(this IRenderer renderer, IVisual visual, IPlatformHandle target, Matrix translation, Matrix transform) + public static void Render(this IRenderingViewport viewport, IVisual visual, IPlatformHandle target, Matrix translation, Matrix transform) { - using (var ctx = renderer.CreateDrawingContext(target)) + using (var ctx = viewport.CreateDrawingContext(target)) ctx.Render(visual, translation, transform); } /// /// Renders the specified visual with the specified transform and clip. /// - /// IRenderer instance + /// IRenderer instance /// An optional platform-specific handle. /// The visual to render. /// The transform. /// An optional clip rectangle. - public static void Render(this IRenderer renderer, IVisual visual, IPlatformHandle target, Matrix transform, Rect? clip = null) + public static void Render(this IRenderingViewport viewport, IVisual visual, IPlatformHandle target, Matrix transform, Rect? clip = null) { - using (var context = renderer.CreateDrawingContext(target)) + using (var context = viewport.CreateDrawingContext(target)) context.Render(visual, transform, clip); } diff --git a/src/Perspex.SceneGraph/Visual.cs b/src/Perspex.SceneGraph/Visual.cs index 46020d8e07..45ac797d99 100644 --- a/src/Perspex.SceneGraph/Visual.cs +++ b/src/Perspex.SceneGraph/Visual.cs @@ -22,7 +22,7 @@ namespace Perspex /// /// /// The class acts as a node in the Perspex scene graph and holds - /// all the information needed for an to render the control. + /// all the information needed for an to render the control. /// To traverse the scene graph (aka Visual Tree), use the extension methods defined /// in . /// @@ -222,9 +222,9 @@ namespace Perspex .OfType() .FirstOrDefault(); - if (root != null && root.RenderManager != null) + if (root != null && root.RenderQueueManager != null) { - root.RenderManager.InvalidateRender(this); + root.RenderQueueManager.InvalidateRender(this); } } diff --git a/src/Windows/Perspex.Direct2D1/Direct2D1Platform.cs b/src/Windows/Perspex.Direct2D1/Direct2D1Platform.cs index 9005a9ffe3..65aa0b06d6 100644 --- a/src/Windows/Perspex.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Perspex.Direct2D1/Direct2D1Platform.cs @@ -41,11 +41,11 @@ namespace Perspex.Direct2D1 return new FormattedTextImpl(text, fontFamily, fontSize, fontStyle, textAlignment, fontWeight); } - public IRenderer CreateRenderer(IPlatformHandle handle, double width, double height) + public IRenderingViewport CreateRenderer(IPlatformHandle handle, double width, double height) { if (handle.HandleDescriptor == "HWND") { - return new Renderer(handle.Handle, width, height); + return new Viewport(handle.Handle, width, height); } else { diff --git a/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs b/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs index 16cda058ce..3faaf762d8 100644 --- a/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs +++ b/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs @@ -39,8 +39,8 @@ namespace Perspex.Direct2D1.Media public void Render(IVisual visual) { - Renderer renderer = new Renderer(_target); - renderer.Render(visual, null); + Viewport viewport = new Viewport(_target); + viewport.Render(visual, null); } } } diff --git a/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs b/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs index 0acb5e07dc..8380b9c200 100644 --- a/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs +++ b/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs @@ -51,7 +51,7 @@ namespace Perspex.Direct2D1.Media scale, translate, out drawRect); - var renderer = new Renderer(intermediate); + var renderer = new Viewport(intermediate); renderer.Render(visual, null, transform, drawRect); diff --git a/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj b/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj index f352a6d7a8..eecdaeef6a 100644 --- a/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj +++ b/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj @@ -89,7 +89,7 @@ - + diff --git a/src/Windows/Perspex.Direct2D1/Renderer.cs b/src/Windows/Perspex.Direct2D1/Viewport.cs similarity index 91% rename from src/Windows/Perspex.Direct2D1/Renderer.cs rename to src/Windows/Perspex.Direct2D1/Viewport.cs index 607270ed69..e53a1c8b91 100644 --- a/src/Windows/Perspex.Direct2D1/Renderer.cs +++ b/src/Windows/Perspex.Direct2D1/Viewport.cs @@ -12,7 +12,7 @@ using DwFactory = SharpDX.DirectWrite.Factory; namespace Perspex.Direct2D1 { - public class Renderer : IRenderer + public class Viewport : IRenderingViewport { /// /// The render target. @@ -20,12 +20,12 @@ namespace Perspex.Direct2D1 private readonly RenderTarget _renderTarget; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The window handle. /// The width of the window. /// The height of the window. - public Renderer(IntPtr hwnd, double width, double height) + public Viewport(IntPtr hwnd, double width, double height) { Direct2DFactory = PerspexLocator.Current.GetService(); DirectWriteFactory = PerspexLocator.Current.GetService(); @@ -48,10 +48,10 @@ namespace Perspex.Direct2D1 } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The render target. - public Renderer(RenderTarget renderTarget) + public Viewport(RenderTarget renderTarget) { Direct2DFactory = PerspexLocator.Current.GetService(); DirectWriteFactory = PerspexLocator.Current.GetService(); diff --git a/tests/Perspex.Controls.UnitTests/ControlTests.cs b/tests/Perspex.Controls.UnitTests/ControlTests.cs index 4a801fc0e9..d031467ca2 100644 --- a/tests/Perspex.Controls.UnitTests/ControlTests.cs +++ b/tests/Perspex.Controls.UnitTests/ControlTests.cs @@ -76,12 +76,12 @@ namespace Perspex.Controls.UnitTests get { throw new NotImplementedException(); } } - public IRenderer Renderer + public IRenderingViewport Viewport { get { throw new NotImplementedException(); } } - public IRenderManager RenderManager + public IRenderQueueManager RenderQueueManager { get { throw new NotImplementedException(); } } diff --git a/tests/Perspex.Controls.UnitTests/TestRoot.cs b/tests/Perspex.Controls.UnitTests/TestRoot.cs index 6f564550d2..a35bfc50ce 100644 --- a/tests/Perspex.Controls.UnitTests/TestRoot.cs +++ b/tests/Perspex.Controls.UnitTests/TestRoot.cs @@ -15,12 +15,12 @@ namespace Perspex.Controls.UnitTests public ILayoutManager LayoutManager => new Mock().Object; - public IRenderer Renderer + public IRenderingViewport Viewport { get { throw new NotImplementedException(); } } - public IRenderManager RenderManager + public IRenderQueueManager RenderQueueManager { get { throw new NotImplementedException(); } } diff --git a/tests/Perspex.Controls.UnitTests/TopLevelTests.cs b/tests/Perspex.Controls.UnitTests/TopLevelTests.cs index 7c8f6a52b4..5b8c08e8e2 100644 --- a/tests/Perspex.Controls.UnitTests/TopLevelTests.cs +++ b/tests/Perspex.Controls.UnitTests/TopLevelTests.cs @@ -180,7 +180,7 @@ namespace Perspex.Controls.UnitTests var target = new TestTopLevel(impl.Object); completed.OnNext(Unit.Default); - var renderManagerMock = Mock.Get(PerspexLocator.Current.GetService()); + var renderManagerMock = Mock.Get(PerspexLocator.Current.GetService()); renderManagerMock.Verify(x => x.InvalidateRender(target)); } } @@ -313,7 +313,7 @@ namespace Perspex.Controls.UnitTests var globalStyles = new Mock(); var layoutManager = fixture.Create(); var renderInterface = fixture.Create(); - var renderManager = fixture.Create(); + var renderManager = fixture.Create(); var windowImpl = new Mock(); var theme = new Styles(); @@ -327,7 +327,7 @@ namespace Perspex.Controls.UnitTests .Bind().ToConstant(layoutManager) .Bind().ToConstant(renderInterface) .Bind().ToConstant(new Mock().Object) - .Bind().ToConstant(renderManager) + .Bind().ToConstant(renderManager) .Bind().ToConstant(new Styler()); } diff --git a/tests/Perspex.Layout.UnitTests/FullLayoutTests.cs b/tests/Perspex.Layout.UnitTests/FullLayoutTests.cs index fb714e5278..c9df6639cd 100644 --- a/tests/Perspex.Layout.UnitTests/FullLayoutTests.cs +++ b/tests/Perspex.Layout.UnitTests/FullLayoutTests.cs @@ -134,7 +134,7 @@ namespace Perspex.Layout.UnitTests var formattedText = fixture.Create(); var globalStyles = new Mock(); var renderInterface = fixture.Create(); - var renderManager = fixture.Create(); + var renderManager = fixture.Create(); var theme = new DefaultTheme(); var windowImpl = new Mock(); @@ -148,7 +148,7 @@ namespace Perspex.Layout.UnitTests .Bind().ToConstant(new LayoutManager()) .Bind().ToConstant(renderInterface) .Bind().ToConstant(new Mock().Object) - .Bind().ToConstant(renderManager) + .Bind().ToConstant(renderManager) .Bind().ToConstant(new Styler()) .Bind().ToConstant(windowImpl.Object); } diff --git a/tests/Perspex.SceneGraph.UnitTests/TestRoot.cs b/tests/Perspex.SceneGraph.UnitTests/TestRoot.cs index 41215cfa08..8b447e42bb 100644 --- a/tests/Perspex.SceneGraph.UnitTests/TestRoot.cs +++ b/tests/Perspex.SceneGraph.UnitTests/TestRoot.cs @@ -9,12 +9,12 @@ namespace Perspex.SceneGraph.UnitTests { public class TestRoot : TestVisual, IRenderRoot { - public IRenderer Renderer + public IRenderingViewport Viewport { get { throw new NotImplementedException(); } } - public IRenderManager RenderManager + public IRenderQueueManager RenderQueueManager { get { throw new NotImplementedException(); } } From f4f3d572a621ef48f3f0f0ec2634522f6247c634 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 15:04:58 +0300 Subject: [PATCH 07/28] Renamed IRenderingViewport to IRenderTarget --- src/Gtk/Perspex.Cairo/CairoPlatform.cs | 4 ++-- .../Media/Imaging/RenderTargetBitmapImpl.cs | 8 ++++---- src/Gtk/Perspex.Cairo/Media/TileBrushes.cs | 2 +- src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj | 2 +- .../{Viewport.cs => RenderTarget.cs} | 8 ++++---- src/Perspex.Controls/TopLevel.cs | 4 ++-- .../Perspex.SceneGraph.csproj | 2 +- .../Platform/IPlatformRenderInterface.cs | 4 ++-- ...IRenderingViewport.cs => IRenderTarget.cs} | 2 +- .../Rendering/RendererBase.cs | 20 +++++++++---------- src/Perspex.SceneGraph/Visual.cs | 2 +- .../Perspex.Direct2D1/Direct2D1Platform.cs | 4 ++-- .../Perspex.Direct2D1/Media/DrawingContext.cs | 4 ++-- .../Perspex.Direct2D1/Media/ImageBrushImpl.cs | 4 ++-- .../Media/Imaging/RenderTargetBitmapImpl.cs | 4 ++-- .../Media/PerspexTextRenderer.cs | 4 ++-- .../Media/VisualBrushImpl.cs | 4 ++-- .../Perspex.Direct2D1.csproj | 2 +- .../Perspex.Direct2D1/PrimitiveExtensions.cs | 2 +- .../{Viewport.cs => RenderTarget.cs} | 12 +++++------ .../ControlTests.cs | 2 +- tests/Perspex.Controls.UnitTests/TestRoot.cs | 2 +- .../Perspex.SceneGraph.UnitTests/TestRoot.cs | 2 +- 23 files changed, 52 insertions(+), 52 deletions(-) rename src/Gtk/Perspex.Cairo/{Viewport.cs => RenderTarget.cs} (89%) rename src/Perspex.SceneGraph/Platform/{IRenderingViewport.cs => IRenderTarget.cs} (95%) rename src/Windows/Perspex.Direct2D1/{Viewport.cs => RenderTarget.cs} (88%) diff --git a/src/Gtk/Perspex.Cairo/CairoPlatform.cs b/src/Gtk/Perspex.Cairo/CairoPlatform.cs index 7d4b5421ee..ba0d8881c1 100644 --- a/src/Gtk/Perspex.Cairo/CairoPlatform.cs +++ b/src/Gtk/Perspex.Cairo/CairoPlatform.cs @@ -36,9 +36,9 @@ namespace Perspex.Cairo return new FormattedTextImpl(s_pangoContext, text, fontFamily, fontSize, fontStyle, textAlignment, fontWeight); } - public IRenderingViewport CreateRenderer(IPlatformHandle handle, double width, double height) + public IRenderTarget CreateRenderer(IPlatformHandle handle, double width, double height) { - return new Viewport(handle, width, height); + return new RenderTarget(handle, width, height); } public IRenderTargetBitmapImpl CreateRenderTargetBitmap(int width, int height) diff --git a/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs b/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs index a35c037875..452ee67854 100644 --- a/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs +++ b/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs @@ -14,7 +14,7 @@ namespace Perspex.Cairo.Media.Imaging public RenderTargetBitmapImpl(Cairo.ImageSurface surface) { Surface = surface; - viewport = new Viewport(Surface); + renderTarget = new RenderTarget(Surface); } public int PixelWidth => Surface.Width; @@ -23,7 +23,7 @@ namespace Perspex.Cairo.Media.Imaging public void Dispose() { - viewport.Dispose(); + renderTarget.Dispose(); } public Cairo.ImageSurface Surface @@ -31,10 +31,10 @@ namespace Perspex.Cairo.Media.Imaging get; } - private Viewport viewport; + private RenderTarget renderTarget; public void Render(IVisual visual) { - viewport.Render(visual, new PlatformHandle(IntPtr.Zero, "RTB")); + renderTarget.Render(visual, new PlatformHandle(IntPtr.Zero, "RTB")); } public void Save(string fileName) diff --git a/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs b/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs index 0a4c20246f..77710a3282 100644 --- a/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs +++ b/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs @@ -111,7 +111,7 @@ namespace Perspex.Cairo.Media scale, translate, out drawRect); - var renderer = new Viewport(intermediate); + var renderer = new RenderTarget(intermediate); context.Rectangle(drawRect.ToCairo()); context.Clip(); diff --git a/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj b/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj index 3f5d54a26a..77deb8f6b3 100644 --- a/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj +++ b/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj @@ -61,7 +61,7 @@ - + diff --git a/src/Gtk/Perspex.Cairo/Viewport.cs b/src/Gtk/Perspex.Cairo/RenderTarget.cs similarity index 89% rename from src/Gtk/Perspex.Cairo/Viewport.cs rename to src/Gtk/Perspex.Cairo/RenderTarget.cs index 2191611f15..1b428e36f4 100644 --- a/src/Gtk/Perspex.Cairo/Viewport.cs +++ b/src/Gtk/Perspex.Cairo/RenderTarget.cs @@ -15,22 +15,22 @@ namespace Perspex.Cairo /// /// A cairo renderer. /// - public class Viewport : IRenderingViewport + public class RenderTarget : IRenderTarget { private readonly Surface _surface; private Gdk.Window _window; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The window handle. /// The width of the window. /// The height of the window. - public Viewport(IPlatformHandle handle, double width, double height) + public RenderTarget(IPlatformHandle handle, double width, double height) { } - public Viewport(ImageSurface surface) + public RenderTarget(ImageSurface surface) { _surface = surface; } diff --git a/src/Perspex.Controls/TopLevel.cs b/src/Perspex.Controls/TopLevel.cs index a34d7a1ad0..1c0ac1e525 100644 --- a/src/Perspex.Controls/TopLevel.cs +++ b/src/Perspex.Controls/TopLevel.cs @@ -45,7 +45,7 @@ namespace Perspex.Controls PerspexProperty.Register(nameof(IInputRoot.PointerOverElement)); private readonly IRenderQueueManager _renderQueueManager; - private readonly IRenderingViewport _viewport; + private readonly IRenderTarget _renderTarget; private readonly IInputManager _inputManager; private readonly IAccessKeyHandler _accessKeyHandler; private readonly IKeyboardNavigationHandler _keyboardNavigationHandler; @@ -107,7 +107,7 @@ namespace Perspex.Controls if (renderInterface != null) { - _viewport = renderInterface.CreateRenderer(PlatformImpl.Handle, clientSize.Width, clientSize.Height); + _renderTarget = renderInterface.CreateRenderer(PlatformImpl.Handle, clientSize.Width, clientSize.Height); } if (LayoutManager != null) diff --git a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj index dafed3ddd9..7824b398e6 100644 --- a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj +++ b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj @@ -105,7 +105,7 @@ - + diff --git a/src/Perspex.SceneGraph/Platform/IPlatformRenderInterface.cs b/src/Perspex.SceneGraph/Platform/IPlatformRenderInterface.cs index 9adf05e2e4..e79da32923 100644 --- a/src/Perspex.SceneGraph/Platform/IPlatformRenderInterface.cs +++ b/src/Perspex.SceneGraph/Platform/IPlatformRenderInterface.cs @@ -49,8 +49,8 @@ namespace Perspex.Platform /// The platform handle for the renderer. /// The initial width of the render. /// The initial height of the render. - /// An . - IRenderingViewport CreateRenderer(IPlatformHandle handle, double width, double height); + /// An . + IRenderTarget CreateRenderer(IPlatformHandle handle, double width, double height); /// /// Creates a render target bitmap implementation. diff --git a/src/Perspex.SceneGraph/Platform/IRenderingViewport.cs b/src/Perspex.SceneGraph/Platform/IRenderTarget.cs similarity index 95% rename from src/Perspex.SceneGraph/Platform/IRenderingViewport.cs rename to src/Perspex.SceneGraph/Platform/IRenderTarget.cs index ef9a8452e7..2ea2889348 100644 --- a/src/Perspex.SceneGraph/Platform/IRenderingViewport.cs +++ b/src/Perspex.SceneGraph/Platform/IRenderTarget.cs @@ -15,7 +15,7 @@ namespace Perspex.Platform /// as RenderBase has a default implementation for the non-platform specific parts of a /// renderer. /// - public interface IRenderingViewport : IDisposable + public interface IRenderTarget : IDisposable { /// /// Creates an for a rendering session. diff --git a/src/Perspex.SceneGraph/Rendering/RendererBase.cs b/src/Perspex.SceneGraph/Rendering/RendererBase.cs index e0a886f66f..3f254afe61 100644 --- a/src/Perspex.SceneGraph/Rendering/RendererBase.cs +++ b/src/Perspex.SceneGraph/Rendering/RendererBase.cs @@ -12,47 +12,47 @@ namespace Perspex.Rendering /// Base class for standard renderers. /// /// - /// This class provides implements the platform-independent parts of . + /// This class provides implements the platform-independent parts of . /// public static class RendererMixin { /// /// Renders the specified visual. /// - /// IRenderer instance + /// IRenderer instance /// The visual to render. /// An optional platform-specific handle. - public static void Render(this IRenderingViewport viewport, IVisual visual, IPlatformHandle target) + public static void Render(this IRenderTarget renderTarget, IVisual visual, IPlatformHandle target) { - using (var ctx = viewport.CreateDrawingContext(target)) + using (var ctx = renderTarget.CreateDrawingContext(target)) ctx.Render(visual); } /// /// Renders the specified visual. /// - /// IRenderer instance + /// IRenderer instance /// An optional platform-specific handle. /// The visual to render. /// The current translation. /// The current transform. - public static void Render(this IRenderingViewport viewport, IVisual visual, IPlatformHandle target, Matrix translation, Matrix transform) + public static void Render(this IRenderTarget renderTarget, IVisual visual, IPlatformHandle target, Matrix translation, Matrix transform) { - using (var ctx = viewport.CreateDrawingContext(target)) + using (var ctx = renderTarget.CreateDrawingContext(target)) ctx.Render(visual, translation, transform); } /// /// Renders the specified visual with the specified transform and clip. /// - /// IRenderer instance + /// IRenderer instance /// An optional platform-specific handle. /// The visual to render. /// The transform. /// An optional clip rectangle. - public static void Render(this IRenderingViewport viewport, IVisual visual, IPlatformHandle target, Matrix transform, Rect? clip = null) + public static void Render(this IRenderTarget renderTarget, IVisual visual, IPlatformHandle target, Matrix transform, Rect? clip = null) { - using (var context = viewport.CreateDrawingContext(target)) + using (var context = renderTarget.CreateDrawingContext(target)) context.Render(visual, transform, clip); } diff --git a/src/Perspex.SceneGraph/Visual.cs b/src/Perspex.SceneGraph/Visual.cs index 45ac797d99..e835c6a76c 100644 --- a/src/Perspex.SceneGraph/Visual.cs +++ b/src/Perspex.SceneGraph/Visual.cs @@ -22,7 +22,7 @@ namespace Perspex /// /// /// The class acts as a node in the Perspex scene graph and holds - /// all the information needed for an to render the control. + /// all the information needed for an to render the control. /// To traverse the scene graph (aka Visual Tree), use the extension methods defined /// in . /// diff --git a/src/Windows/Perspex.Direct2D1/Direct2D1Platform.cs b/src/Windows/Perspex.Direct2D1/Direct2D1Platform.cs index 65aa0b06d6..fef168bd27 100644 --- a/src/Windows/Perspex.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Perspex.Direct2D1/Direct2D1Platform.cs @@ -41,11 +41,11 @@ namespace Perspex.Direct2D1 return new FormattedTextImpl(text, fontFamily, fontSize, fontStyle, textAlignment, fontWeight); } - public IRenderingViewport CreateRenderer(IPlatformHandle handle, double width, double height) + public IRenderTarget CreateRenderer(IPlatformHandle handle, double width, double height) { if (handle.HandleDescriptor == "HWND") { - return new Viewport(handle.Handle, width, height); + return new RenderTarget(handle.Handle, width, height); } else { diff --git a/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs b/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs index 039f6c30e0..0b6abe9353 100644 --- a/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs +++ b/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs @@ -18,7 +18,7 @@ namespace Perspex.Direct2D1.Media /// /// The Direct2D1 render target. /// - private readonly RenderTarget _renderTarget; + private readonly SharpDX.Direct2D1.RenderTarget _renderTarget; /// /// The DirectWrite factory. @@ -31,7 +31,7 @@ namespace Perspex.Direct2D1.Media /// The render target to draw to. /// The DirectWrite factory. public DrawingContext( - RenderTarget renderTarget, + SharpDX.Direct2D1.RenderTarget renderTarget, SharpDX.DirectWrite.Factory directWriteFactory) { _renderTarget = renderTarget; diff --git a/src/Windows/Perspex.Direct2D1/Media/ImageBrushImpl.cs b/src/Windows/Perspex.Direct2D1/Media/ImageBrushImpl.cs index bbadb758c4..c518b6438f 100644 --- a/src/Windows/Perspex.Direct2D1/Media/ImageBrushImpl.cs +++ b/src/Windows/Perspex.Direct2D1/Media/ImageBrushImpl.cs @@ -11,7 +11,7 @@ namespace Perspex.Direct2D1.Media { public ImageBrushImpl( ImageBrush brush, - RenderTarget target, + SharpDX.Direct2D1.RenderTarget target, Size targetSize) { if (brush.Source == null) @@ -59,7 +59,7 @@ namespace Perspex.Direct2D1.Media private BitmapBrush CreateDirectBrush( ImageBrush brush, - RenderTarget target, + SharpDX.Direct2D1.RenderTarget target, Bitmap image, Rect sourceRect, Rect destinationRect) diff --git a/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs b/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs index 3faaf762d8..c08d48e225 100644 --- a/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs +++ b/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs @@ -39,8 +39,8 @@ namespace Perspex.Direct2D1.Media public void Render(IVisual visual) { - Viewport viewport = new Viewport(_target); - viewport.Render(visual, null); + RenderTarget renderTarget = new RenderTarget(_target); + renderTarget.Render(visual, null); } } } diff --git a/src/Windows/Perspex.Direct2D1/Media/PerspexTextRenderer.cs b/src/Windows/Perspex.Direct2D1/Media/PerspexTextRenderer.cs index dbd56cfa4d..297dcdb581 100644 --- a/src/Windows/Perspex.Direct2D1/Media/PerspexTextRenderer.cs +++ b/src/Windows/Perspex.Direct2D1/Media/PerspexTextRenderer.cs @@ -12,13 +12,13 @@ namespace Perspex.Direct2D1.Media { private readonly DrawingContext _context; - private readonly RenderTarget _renderTarget; + private readonly SharpDX.Direct2D1.RenderTarget _renderTarget; private readonly Brush _foreground; public PerspexTextRenderer( DrawingContext context, - RenderTarget target, + SharpDX.Direct2D1.RenderTarget target, Brush foreground) { _context = context; diff --git a/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs b/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs index 8380b9c200..5bb191a4bc 100644 --- a/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs +++ b/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs @@ -13,7 +13,7 @@ namespace Perspex.Direct2D1.Media { public VisualBrushImpl( VisualBrush brush, - RenderTarget target, + SharpDX.Direct2D1.RenderTarget target, Size targetSize) { var visual = brush.Visual; @@ -51,7 +51,7 @@ namespace Perspex.Direct2D1.Media scale, translate, out drawRect); - var renderer = new Viewport(intermediate); + var renderer = new RenderTarget(intermediate); renderer.Render(visual, null, transform, drawRect); diff --git a/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj b/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj index eecdaeef6a..0f4ec68289 100644 --- a/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj +++ b/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj @@ -89,7 +89,7 @@ - + diff --git a/src/Windows/Perspex.Direct2D1/PrimitiveExtensions.cs b/src/Windows/Perspex.Direct2D1/PrimitiveExtensions.cs index 2364521ed0..fac270dd7c 100644 --- a/src/Windows/Perspex.Direct2D1/PrimitiveExtensions.cs +++ b/src/Windows/Perspex.Direct2D1/PrimitiveExtensions.cs @@ -69,7 +69,7 @@ namespace Perspex.Direct2D1 /// The pen to convert. /// The render target. /// The Direct2D brush. - public static StrokeStyle ToDirect2DStrokeStyle(this Perspex.Media.Pen pen, RenderTarget target) + public static StrokeStyle ToDirect2DStrokeStyle(this Perspex.Media.Pen pen, SharpDX.Direct2D1.RenderTarget target) { if (pen.DashStyle != null) { diff --git a/src/Windows/Perspex.Direct2D1/Viewport.cs b/src/Windows/Perspex.Direct2D1/RenderTarget.cs similarity index 88% rename from src/Windows/Perspex.Direct2D1/Viewport.cs rename to src/Windows/Perspex.Direct2D1/RenderTarget.cs index e53a1c8b91..95259f324b 100644 --- a/src/Windows/Perspex.Direct2D1/Viewport.cs +++ b/src/Windows/Perspex.Direct2D1/RenderTarget.cs @@ -12,20 +12,20 @@ using DwFactory = SharpDX.DirectWrite.Factory; namespace Perspex.Direct2D1 { - public class Viewport : IRenderingViewport + public class RenderTarget : IRenderTarget { /// /// The render target. /// - private readonly RenderTarget _renderTarget; + private readonly SharpDX.Direct2D1.RenderTarget _renderTarget; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The window handle. /// The width of the window. /// The height of the window. - public Viewport(IntPtr hwnd, double width, double height) + public RenderTarget(IntPtr hwnd, double width, double height) { Direct2DFactory = PerspexLocator.Current.GetService(); DirectWriteFactory = PerspexLocator.Current.GetService(); @@ -48,10 +48,10 @@ namespace Perspex.Direct2D1 } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The render target. - public Viewport(RenderTarget renderTarget) + public RenderTarget(SharpDX.Direct2D1.RenderTarget renderTarget) { Direct2DFactory = PerspexLocator.Current.GetService(); DirectWriteFactory = PerspexLocator.Current.GetService(); diff --git a/tests/Perspex.Controls.UnitTests/ControlTests.cs b/tests/Perspex.Controls.UnitTests/ControlTests.cs index d031467ca2..d86733de3d 100644 --- a/tests/Perspex.Controls.UnitTests/ControlTests.cs +++ b/tests/Perspex.Controls.UnitTests/ControlTests.cs @@ -76,7 +76,7 @@ namespace Perspex.Controls.UnitTests get { throw new NotImplementedException(); } } - public IRenderingViewport Viewport + public IRenderTarget RenderTarget { get { throw new NotImplementedException(); } } diff --git a/tests/Perspex.Controls.UnitTests/TestRoot.cs b/tests/Perspex.Controls.UnitTests/TestRoot.cs index a35bfc50ce..10973f7c9c 100644 --- a/tests/Perspex.Controls.UnitTests/TestRoot.cs +++ b/tests/Perspex.Controls.UnitTests/TestRoot.cs @@ -15,7 +15,7 @@ namespace Perspex.Controls.UnitTests public ILayoutManager LayoutManager => new Mock().Object; - public IRenderingViewport Viewport + public IRenderTarget RenderTarget { get { throw new NotImplementedException(); } } diff --git a/tests/Perspex.SceneGraph.UnitTests/TestRoot.cs b/tests/Perspex.SceneGraph.UnitTests/TestRoot.cs index 8b447e42bb..99a1fd0d4a 100644 --- a/tests/Perspex.SceneGraph.UnitTests/TestRoot.cs +++ b/tests/Perspex.SceneGraph.UnitTests/TestRoot.cs @@ -9,7 +9,7 @@ namespace Perspex.SceneGraph.UnitTests { public class TestRoot : TestVisual, IRenderRoot { - public IRenderingViewport Viewport + public IRenderTarget RenderTarget { get { throw new NotImplementedException(); } } From 9107a6e9a8e5419af9fd0266413bf2417a069dfd Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 15:24:27 +0300 Subject: [PATCH 08/28] Unify window and bitmap rendering --- .../Media/Imaging/RenderTargetBitmapImpl.cs | 21 ++++++++++++------- src/Gtk/Perspex.Cairo/Media/TileBrushes.cs | 2 +- src/Gtk/Perspex.Cairo/RenderTarget.cs | 15 +++++++------ src/Gtk/Perspex.Gtk/WindowImpl.cs | 4 ++-- .../Platform/ITopLevelImpl.cs | 2 +- .../Platform/ITopLevelRenderer.cs | 4 ++-- .../Media/Imaging/RenderTargetBitmap.cs | 1 + .../Platform/IRenderTarget.cs | 4 +--- .../Platform/IRenderTargetBitmapImpl.cs | 10 +-------- .../Rendering/RendererBase.cs | 15 ++++++------- .../Media/Imaging/RenderTargetBitmapImpl.cs | 8 ++++--- .../Media/VisualBrushImpl.cs | 2 +- src/Windows/Perspex.Direct2D1/RenderTarget.cs | 3 +-- src/Windows/Perspex.Win32/WindowImpl.cs | 4 ++-- 14 files changed, 47 insertions(+), 48 deletions(-) diff --git a/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs b/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs index 452ee67854..0b9183d928 100644 --- a/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs +++ b/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; +using Perspex.Media; using Perspex.Platform; using Perspex.Rendering; @@ -11,10 +12,12 @@ namespace Perspex.Cairo.Media.Imaging public class RenderTargetBitmapImpl : IRenderTargetBitmapImpl { + + private readonly RenderTarget _renderTarget; public RenderTargetBitmapImpl(Cairo.ImageSurface surface) { Surface = surface; - renderTarget = new RenderTarget(Surface); + _renderTarget = new RenderTarget(Surface); } public int PixelWidth => Surface.Width; @@ -23,7 +26,7 @@ namespace Perspex.Cairo.Media.Imaging public void Dispose() { - renderTarget.Dispose(); + _renderTarget.Dispose(); } public Cairo.ImageSurface Surface @@ -31,15 +34,19 @@ namespace Perspex.Cairo.Media.Imaging get; } - private RenderTarget renderTarget; - public void Render(IVisual visual) + public void Save(string fileName) { - renderTarget.Render(visual, new PlatformHandle(IntPtr.Zero, "RTB")); + Surface.WriteToPng(fileName); } - public void Save(string fileName) + public IDrawingContext CreateDrawingContext() { - Surface.WriteToPng(fileName); + return _renderTarget.CreateDrawingContext(); + } + + void IRenderTarget.Resize(int width, int height) + { + throw new NotSupportedException(); } } } \ No newline at end of file diff --git a/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs b/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs index 77710a3282..fd1f457a95 100644 --- a/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs +++ b/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs @@ -116,7 +116,7 @@ namespace Perspex.Cairo.Media context.Rectangle(drawRect.ToCairo()); context.Clip(); context.Transform(transform.ToCairo()); - renderer.Render(visual, new PlatformHandle(IntPtr.Zero, "RTB"), transform, drawRect); + renderer.Render(visual, transform, drawRect); var result = new SurfacePattern(intermediate); diff --git a/src/Gtk/Perspex.Cairo/RenderTarget.cs b/src/Gtk/Perspex.Cairo/RenderTarget.cs index 1b428e36f4..83edc10f31 100644 --- a/src/Gtk/Perspex.Cairo/RenderTarget.cs +++ b/src/Gtk/Perspex.Cairo/RenderTarget.cs @@ -17,6 +17,7 @@ namespace Perspex.Cairo /// public class RenderTarget : IRenderTarget { + private readonly IPlatformHandle _handle; private readonly Surface _surface; private Gdk.Window _window; @@ -28,6 +29,7 @@ namespace Perspex.Cairo /// The height of the window. public RenderTarget(IPlatformHandle handle, double width, double height) { + _handle = handle; } public RenderTarget(ImageSurface surface) @@ -51,21 +53,22 @@ namespace Perspex.Cairo /// /// The platform-specific handle. /// A surface wrapped in an . - public IDrawingContext CreateDrawingContext(IPlatformHandle handle) + public IDrawingContext CreateDrawingContext() { - switch (handle.HandleDescriptor) + if(_surface != null) + return new DrawingContext(_surface); + + switch (_handle.HandleDescriptor) { - case "RTB": - return new DrawingContext(_surface); case "GdkWindow": if (_window == null) - _window = new Gdk.Window(handle.Handle); + _window = new Gdk.Window(_handle.Handle); return new DrawingContext(_window); default: throw new NotSupportedException(string.Format( "Don't know how to create a Cairo renderer from a '{0}' handle", - handle.HandleDescriptor)); + _handle.HandleDescriptor)); } } diff --git a/src/Gtk/Perspex.Gtk/WindowImpl.cs b/src/Gtk/Perspex.Gtk/WindowImpl.cs index 1914207d08..c6076a85f8 100644 --- a/src/Gtk/Perspex.Gtk/WindowImpl.cs +++ b/src/Gtk/Perspex.Gtk/WindowImpl.cs @@ -83,7 +83,7 @@ namespace Perspex.Gtk public Action Input { get; set; } - public Action Paint { get; set; } + public Action Paint { get; set; } public Action Resized { get; set; } @@ -223,7 +223,7 @@ namespace Perspex.Gtk protected override bool OnExposeEvent(EventExpose evnt) { - Paint(evnt.Area.ToPerspex(), GetHandle(evnt.Window)); + Paint(evnt.Area.ToPerspex()); return true; } diff --git a/src/Perspex.Controls/Platform/ITopLevelImpl.cs b/src/Perspex.Controls/Platform/ITopLevelImpl.cs index 1cbc5f7c60..053c340b27 100644 --- a/src/Perspex.Controls/Platform/ITopLevelImpl.cs +++ b/src/Perspex.Controls/Platform/ITopLevelImpl.cs @@ -22,7 +22,7 @@ namespace Perspex.Platform Action Input { get; set; } - Action Paint { get; set; } + Action Paint { get; set; } Action Resized { get; set; } diff --git a/src/Perspex.Controls/Platform/ITopLevelRenderer.cs b/src/Perspex.Controls/Platform/ITopLevelRenderer.cs index 74afcceeb8..fa71860f7d 100644 --- a/src/Perspex.Controls/Platform/ITopLevelRenderer.cs +++ b/src/Perspex.Controls/Platform/ITopLevelRenderer.cs @@ -44,9 +44,9 @@ namespace Perspex.Controls.Platform resources.Add(queueManager.RenderNeeded.Subscribe(_ => topLevel.PlatformImpl.Invalidate(new Rect(topLevel.ClientSize)))); - topLevel.PlatformImpl.Paint = (rect, handle) => + topLevel.PlatformImpl.Paint = rect => { - viewport.Render(topLevel, handle); + viewport.Render(topLevel); queueManager.RenderFinished(); }; diff --git a/src/Perspex.SceneGraph/Media/Imaging/RenderTargetBitmap.cs b/src/Perspex.SceneGraph/Media/Imaging/RenderTargetBitmap.cs index 90b83dff6b..0d751d61c6 100644 --- a/src/Perspex.SceneGraph/Media/Imaging/RenderTargetBitmap.cs +++ b/src/Perspex.SceneGraph/Media/Imaging/RenderTargetBitmap.cs @@ -3,6 +3,7 @@ using System; using Perspex.Platform; +using Perspex.Rendering; namespace Perspex.Media.Imaging { diff --git a/src/Perspex.SceneGraph/Platform/IRenderTarget.cs b/src/Perspex.SceneGraph/Platform/IRenderTarget.cs index 2ea2889348..5634d622cd 100644 --- a/src/Perspex.SceneGraph/Platform/IRenderTarget.cs +++ b/src/Perspex.SceneGraph/Platform/IRenderTarget.cs @@ -20,9 +20,7 @@ namespace Perspex.Platform /// /// Creates an for a rendering session. /// - /// The handle to use to create the context. - /// An . - IDrawingContext CreateDrawingContext(IPlatformHandle target); + IDrawingContext CreateDrawingContext(); /// /// Resizes the rendered viewport. diff --git a/src/Perspex.SceneGraph/Platform/IRenderTargetBitmapImpl.cs b/src/Perspex.SceneGraph/Platform/IRenderTargetBitmapImpl.cs index 9e1b0e6cdd..679e243664 100644 --- a/src/Perspex.SceneGraph/Platform/IRenderTargetBitmapImpl.cs +++ b/src/Perspex.SceneGraph/Platform/IRenderTargetBitmapImpl.cs @@ -9,15 +9,7 @@ namespace Perspex.Platform /// Defines the platform-specific interface for a /// . /// - public interface IRenderTargetBitmapImpl : IBitmapImpl, IDisposable + public interface IRenderTargetBitmapImpl : IBitmapImpl, IRenderTarget { - /// - /// Renders an into the bitmap. - /// - /// The visual to render. - /// - /// Before calling this method, ensure that has been measured. - /// - void Render(IVisual visual); } } diff --git a/src/Perspex.SceneGraph/Rendering/RendererBase.cs b/src/Perspex.SceneGraph/Rendering/RendererBase.cs index 3f254afe61..7281ac516b 100644 --- a/src/Perspex.SceneGraph/Rendering/RendererBase.cs +++ b/src/Perspex.SceneGraph/Rendering/RendererBase.cs @@ -21,10 +21,9 @@ namespace Perspex.Rendering /// /// IRenderer instance /// The visual to render. - /// An optional platform-specific handle. - public static void Render(this IRenderTarget renderTarget, IVisual visual, IPlatformHandle target) + public static void Render(this IRenderTarget renderTarget, IVisual visual) { - using (var ctx = renderTarget.CreateDrawingContext(target)) + using (var ctx = renderTarget.CreateDrawingContext()) ctx.Render(visual); } @@ -32,13 +31,12 @@ namespace Perspex.Rendering /// Renders the specified visual. /// /// IRenderer instance - /// An optional platform-specific handle. /// The visual to render. /// The current translation. /// The current transform. - public static void Render(this IRenderTarget renderTarget, IVisual visual, IPlatformHandle target, Matrix translation, Matrix transform) + public static void Render(this IRenderTarget renderTarget, IVisual visual, Matrix translation, Matrix transform) { - using (var ctx = renderTarget.CreateDrawingContext(target)) + using (var ctx = renderTarget.CreateDrawingContext()) ctx.Render(visual, translation, transform); } @@ -46,13 +44,12 @@ namespace Perspex.Rendering /// Renders the specified visual with the specified transform and clip. /// /// IRenderer instance - /// An optional platform-specific handle. /// The visual to render. /// The transform. /// An optional clip rectangle. - public static void Render(this IRenderTarget renderTarget, IVisual visual, IPlatformHandle target, Matrix transform, Rect? clip = null) + public static void Render(this IRenderTarget renderTarget, IVisual visual, Matrix transform, Rect? clip = null) { - using (var context = renderTarget.CreateDrawingContext(target)) + using (var context = renderTarget.CreateDrawingContext()) context.Render(visual, transform, clip); } diff --git a/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs b/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs index c08d48e225..97efa00d47 100644 --- a/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs +++ b/src/Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; +using Perspex.Media; using Perspex.Platform; using Perspex.Rendering; using SharpDX.Direct2D1; @@ -37,10 +38,11 @@ namespace Perspex.Direct2D1.Media // TODO: } - public void Render(IVisual visual) + public IDrawingContext CreateDrawingContext() => new RenderTarget(_target).CreateDrawingContext(); + + void IRenderTarget.Resize(int width, int height) { - RenderTarget renderTarget = new RenderTarget(_target); - renderTarget.Render(visual, null); + throw new NotSupportedException(); } } } diff --git a/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs b/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs index 5bb191a4bc..c57c2b1477 100644 --- a/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs +++ b/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs @@ -53,7 +53,7 @@ namespace Perspex.Direct2D1.Media out drawRect); var renderer = new RenderTarget(intermediate); - renderer.Render(visual, null, transform, drawRect); + renderer.Render(visual, transform, drawRect); this.PlatformBrush = new BitmapBrush( target, diff --git a/src/Windows/Perspex.Direct2D1/RenderTarget.cs b/src/Windows/Perspex.Direct2D1/RenderTarget.cs index 95259f324b..ea6400be80 100644 --- a/src/Windows/Perspex.Direct2D1/RenderTarget.cs +++ b/src/Windows/Perspex.Direct2D1/RenderTarget.cs @@ -94,9 +94,8 @@ namespace Perspex.Direct2D1 /// /// Creates a drawing context for a rendering session. /// - /// The platform handle. Unused. /// An . - public IDrawingContext CreateDrawingContext(IPlatformHandle handle) + public IDrawingContext CreateDrawingContext() { return new DrawingContext(_renderTarget, DirectWriteFactory); } diff --git a/src/Windows/Perspex.Win32/WindowImpl.cs b/src/Windows/Perspex.Win32/WindowImpl.cs index fa3313c232..dda55f4757 100644 --- a/src/Windows/Perspex.Win32/WindowImpl.cs +++ b/src/Windows/Perspex.Win32/WindowImpl.cs @@ -51,7 +51,7 @@ namespace Perspex.Win32 public Action Input { get; set; } - public Action Paint { get; set; } + public Action Paint { get; set; } public Action Resized { get; set; } @@ -405,7 +405,7 @@ namespace Perspex.Win32 { UnmanagedMethods.RECT r; UnmanagedMethods.GetUpdateRect(_hwnd, out r, false); - Paint(new Rect(r.left, r.top, r.right - r.left, r.bottom - r.top), Handle); + Paint(new Rect(r.left, r.top, r.right - r.left, r.bottom - r.top)); UnmanagedMethods.EndPaint(_hwnd, ref ps); } } From 6859f62d120ac5fa5d208f77cdfd6641716286af Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 15:30:00 +0300 Subject: [PATCH 09/28] Make actual RenderTargetBitmap implement IRenderTarget --- .../Media/Imaging/RenderTargetBitmap.cs | 21 +++++++----------- tests/Perspex.RenderTests/TestBase.cs | Bin 4728 -> 4780 bytes 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/Perspex.SceneGraph/Media/Imaging/RenderTargetBitmap.cs b/src/Perspex.SceneGraph/Media/Imaging/RenderTargetBitmap.cs index 0d751d61c6..5b8bbea6da 100644 --- a/src/Perspex.SceneGraph/Media/Imaging/RenderTargetBitmap.cs +++ b/src/Perspex.SceneGraph/Media/Imaging/RenderTargetBitmap.cs @@ -10,7 +10,7 @@ namespace Perspex.Media.Imaging /// /// A bitmap that holds the rendering of a . /// - public class RenderTargetBitmap : Bitmap, IDisposable + public class RenderTargetBitmap : Bitmap, IDisposable, IRenderTarget { /// /// Initializes a new instance of the class. @@ -27,18 +27,6 @@ namespace Perspex.Media.Imaging /// public new IRenderTargetBitmapImpl PlatformImpl => (IRenderTargetBitmapImpl)base.PlatformImpl; - /// - /// Renders an into the bitmap. - /// - /// The visual to render. - /// - /// Before calling this method, ensure that has been measured. - /// - public void Render(IVisual visual) - { - PlatformImpl.Render(visual); - } - /// /// Disposes of the bitmap. /// @@ -58,5 +46,12 @@ namespace Perspex.Media.Imaging IPlatformRenderInterface factory = PerspexLocator.Current.GetService(); return factory.CreateRenderTargetBitmap(width, height); } + + public IDrawingContext CreateDrawingContext() => PlatformImpl.CreateDrawingContext(); + + void IRenderTarget.Resize(int width, int height) + { + throw new NotSupportedException(); + } } } diff --git a/tests/Perspex.RenderTests/TestBase.cs b/tests/Perspex.RenderTests/TestBase.cs index 2940c5ab3135519282bf23ff0e83c7ce7fef6e2f..7344d4d137a7c0485e26dbcc7192274b8425787f 100644 GIT binary patch delta 28 icmeyNvPN}72GitqOak0N45 Date: Wed, 30 Sep 2015 15:31:51 +0300 Subject: [PATCH 10/28] Changed doc for render target --- src/Perspex.SceneGraph/Platform/IRenderTarget.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Perspex.SceneGraph/Platform/IRenderTarget.cs b/src/Perspex.SceneGraph/Platform/IRenderTarget.cs index 5634d622cd..fdbf391a05 100644 --- a/src/Perspex.SceneGraph/Platform/IRenderTarget.cs +++ b/src/Perspex.SceneGraph/Platform/IRenderTarget.cs @@ -7,13 +7,10 @@ using Perspex.Media; namespace Perspex.Platform { /// - /// Defines a renderer. + /// Defines a render target /// /// - /// The interface used to render s. You will usually want to inherit from - /// rather than implementing the whole interface - /// as RenderBase has a default implementation for the non-platform specific parts of a - /// renderer. + /// The interface used for obtaining drawing context from surfaces you can render on. /// public interface IRenderTarget : IDisposable { From 375dc41e585836e824c990670c3b449b609d82fc Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 15:33:18 +0300 Subject: [PATCH 11/28] Moar docs updates --- src/Gtk/Perspex.Cairo/RenderTarget.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Gtk/Perspex.Cairo/RenderTarget.cs b/src/Gtk/Perspex.Cairo/RenderTarget.cs index 83edc10f31..b8de2e2166 100644 --- a/src/Gtk/Perspex.Cairo/RenderTarget.cs +++ b/src/Gtk/Perspex.Cairo/RenderTarget.cs @@ -13,7 +13,7 @@ namespace Perspex.Cairo using global::Cairo; /// - /// A cairo renderer. + /// A cairo render target. /// public class RenderTarget : IRenderTarget { @@ -51,7 +51,6 @@ namespace Perspex.Cairo /// /// Creates a cairo surface that targets a platform-specific resource. /// - /// The platform-specific handle. /// A surface wrapped in an . public IDrawingContext CreateDrawingContext() { @@ -72,10 +71,6 @@ namespace Perspex.Cairo } } - public void Dispose() - { - if (_surface != null) - _surface.Dispose(); - } + public void Dispose() => _surface?.Dispose(); } } From aba953a218c9b6e6107705fc266b846b273744ac Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 15:50:31 +0300 Subject: [PATCH 12/28] TopLevel don't use render target anymore --- src/Perspex.Controls/TopLevel.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Perspex.Controls/TopLevel.cs b/src/Perspex.Controls/TopLevel.cs index 1c0ac1e525..25572b588d 100644 --- a/src/Perspex.Controls/TopLevel.cs +++ b/src/Perspex.Controls/TopLevel.cs @@ -45,7 +45,6 @@ namespace Perspex.Controls PerspexProperty.Register(nameof(IInputRoot.PointerOverElement)); private readonly IRenderQueueManager _renderQueueManager; - private readonly IRenderTarget _renderTarget; private readonly IInputManager _inputManager; private readonly IAccessKeyHandler _accessKeyHandler; private readonly IKeyboardNavigationHandler _keyboardNavigationHandler; @@ -105,11 +104,6 @@ namespace Perspex.Controls Size clientSize = ClientSize = PlatformImpl.ClientSize; - if (renderInterface != null) - { - _renderTarget = renderInterface.CreateRenderer(PlatformImpl.Handle, clientSize.Width, clientSize.Height); - } - if (LayoutManager != null) { LayoutManager.Root = this; From 6f4017e574a17b84e30209b75ec085b5ac28f923 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 15:51:13 +0300 Subject: [PATCH 13/28] Render might occur immediately, when invalidaterender is called --- src/Perspex.SceneGraph/Rendering/RenderQueueManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Perspex.SceneGraph/Rendering/RenderQueueManager.cs b/src/Perspex.SceneGraph/Rendering/RenderQueueManager.cs index 514bb547a6..34e69dd4d7 100644 --- a/src/Perspex.SceneGraph/Rendering/RenderQueueManager.cs +++ b/src/Perspex.SceneGraph/Rendering/RenderQueueManager.cs @@ -34,8 +34,8 @@ namespace Perspex.Rendering { if (!_renderQueued) { - _renderNeeded.OnNext(Unit.Default); _renderQueued = true; + _renderNeeded.OnNext(Unit.Default); } } From a297199e59d9d233b4819d887dfac8c4e2413f23 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 16:27:08 +0300 Subject: [PATCH 14/28] Fixed GTK/Cairo render --- src/Gtk/Perspex.Cairo/CairoPlatform.cs | 6 ++++- src/Gtk/Perspex.Cairo/RenderTarget.cs | 23 ++++--------------- src/Gtk/Perspex.Gtk/WindowImpl.cs | 14 +++++------ src/Perspex.Application/Application.cs | 2 +- .../Platform/ITopLevelRenderer.cs | 4 +++- 5 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/Gtk/Perspex.Cairo/CairoPlatform.cs b/src/Gtk/Perspex.Cairo/CairoPlatform.cs index ba0d8881c1..a4bf08c4ea 100644 --- a/src/Gtk/Perspex.Cairo/CairoPlatform.cs +++ b/src/Gtk/Perspex.Cairo/CairoPlatform.cs @@ -38,7 +38,11 @@ namespace Perspex.Cairo public IRenderTarget CreateRenderer(IPlatformHandle handle, double width, double height) { - return new RenderTarget(handle, width, height); + if (handle.HandleDescriptor != "GtkWindow") + throw new NotSupportedException(string.Format( + "Don't know how to create a Cairo renderer from a '{0}' handle", + handle.HandleDescriptor)); + return new RenderTarget((Gtk.Window)handle, width, height); } public IRenderTargetBitmapImpl CreateRenderTargetBitmap(int width, int height) diff --git a/src/Gtk/Perspex.Cairo/RenderTarget.cs b/src/Gtk/Perspex.Cairo/RenderTarget.cs index b8de2e2166..333c558e8a 100644 --- a/src/Gtk/Perspex.Cairo/RenderTarget.cs +++ b/src/Gtk/Perspex.Cairo/RenderTarget.cs @@ -17,19 +17,18 @@ namespace Perspex.Cairo /// public class RenderTarget : IRenderTarget { - private readonly IPlatformHandle _handle; private readonly Surface _surface; - private Gdk.Window _window; + private Gtk.Window _window; /// /// Initializes a new instance of the class. /// - /// The window handle. + /// The window. /// The width of the window. /// The height of the window. - public RenderTarget(IPlatformHandle handle, double width, double height) + public RenderTarget(Gtk.Window window, double width, double height) { - _handle = handle; + _window = window; } public RenderTarget(ImageSurface surface) @@ -56,19 +55,7 @@ namespace Perspex.Cairo { if(_surface != null) return new DrawingContext(_surface); - - switch (_handle.HandleDescriptor) - { - case "GdkWindow": - if (_window == null) - _window = new Gdk.Window(_handle.Handle); - - return new DrawingContext(_window); - default: - throw new NotSupportedException(string.Format( - "Don't know how to create a Cairo renderer from a '{0}' handle", - _handle.HandleDescriptor)); - } + return new DrawingContext(_window.GdkWindow); } public void Dispose() => _surface?.Dispose(); diff --git a/src/Gtk/Perspex.Gtk/WindowImpl.cs b/src/Gtk/Perspex.Gtk/WindowImpl.cs index c6076a85f8..7b4b149dc3 100644 --- a/src/Gtk/Perspex.Gtk/WindowImpl.cs +++ b/src/Gtk/Perspex.Gtk/WindowImpl.cs @@ -14,12 +14,10 @@ namespace Perspex.Gtk { using Gtk = global::Gtk; - public class WindowImpl : Gtk.Window, IWindowImpl + public class WindowImpl : Gtk.Window, IWindowImpl, IPlatformHandle { private IInputRoot _inputRoot; - - private IPlatformHandle _windowHandle; - + private Size _clientSize; private Gtk.IMContext _imContext; @@ -46,7 +44,6 @@ namespace Perspex.Gtk Events = EventMask.PointerMotionMask | EventMask.ButtonPressMask | EventMask.ButtonReleaseMask; - _windowHandle = new PlatformHandle(Handle, "GtkWindow"); _imContext = new Gtk.IMMulticontext(); _imContext.Commit += ImContext_Commit; } @@ -73,7 +70,8 @@ namespace Perspex.Gtk } } - IPlatformHandle ITopLevelImpl.Handle => _windowHandle; + IPlatformHandle ITopLevelImpl.Handle => this; + public string HandleDescriptor => "GtkWindow"; public Action Activated { get; set; } @@ -94,7 +92,9 @@ namespace Perspex.Gtk public void Invalidate(Rect rect) { - base.GdkWindow.InvalidateRect (new Rectangle ((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height), true); + if (base.GdkWindow != null) + base.GdkWindow.InvalidateRect( + new Rectangle((int) rect.X, (int) rect.Y, (int) rect.Width, (int) rect.Height), true); } public Point PointToScreen(Point point) diff --git a/src/Perspex.Application/Application.cs b/src/Perspex.Application/Application.cs index 88f3a23ffe..334f147b43 100644 --- a/src/Perspex.Application/Application.cs +++ b/src/Perspex.Application/Application.cs @@ -177,7 +177,7 @@ namespace Perspex /// The value of Environment.OSVersion.Platform. protected void InitializeSubsystems(int platformID) { - if (platformID == 4 || platformID == 6) + if (true) { InitializeSubsystem("Perspex.Cairo"); InitializeSubsystem("Perspex.Gtk"); diff --git a/src/Perspex.Controls/Platform/ITopLevelRenderer.cs b/src/Perspex.Controls/Platform/ITopLevelRenderer.cs index fa71860f7d..0f58dac76e 100644 --- a/src/Perspex.Controls/Platform/ITopLevelRenderer.cs +++ b/src/Perspex.Controls/Platform/ITopLevelRenderer.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading.Tasks; using Perspex.Platform; using Perspex.Rendering; +using Perspex.Threading; namespace Perspex.Controls.Platform { @@ -42,7 +43,8 @@ namespace Perspex.Controls.Platform viewport.Resize((int) clientSize.Width, (int) clientSize.Height); })); resources.Add(queueManager.RenderNeeded.Subscribe(_ - => topLevel.PlatformImpl.Invalidate(new Rect(topLevel.ClientSize)))); + => + Dispatcher.UIThread.InvokeAsync(() => topLevel.PlatformImpl.Invalidate(new Rect(topLevel.ClientSize))))); topLevel.PlatformImpl.Paint = rect => { From 9d5eb304a047e86601c9ff2ad5cb8e79d0bf731b Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 16:39:58 +0300 Subject: [PATCH 15/28] Reverted platform detection change --- src/Perspex.Application/Application.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Perspex.Application/Application.cs b/src/Perspex.Application/Application.cs index 334f147b43..88f3a23ffe 100644 --- a/src/Perspex.Application/Application.cs +++ b/src/Perspex.Application/Application.cs @@ -177,7 +177,7 @@ namespace Perspex /// The value of Environment.OSVersion.Platform. protected void InitializeSubsystems(int platformID) { - if (true) + if (platformID == 4 || platformID == 6) { InitializeSubsystem("Perspex.Cairo"); InitializeSubsystem("Perspex.Gtk"); From 476f853be5cdf996f7ec9b192a5f241688063151 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 17:44:28 +0300 Subject: [PATCH 16/28] Simplified render loop, added guard drawing context wrapper --- src/Gtk/Perspex.Cairo/Media/TileBrushes.cs | 12 +-- .../Media/ValidatingDrawingContext.cs | 76 +++++++++++++++++++ .../Perspex.SceneGraph.csproj | 1 + .../Rendering/RendererBase.cs | 74 ++---------------- .../Media/VisualBrushImpl.cs | 8 +- src/Windows/Perspex.Direct2D1/RenderTarget.cs | 12 ++- 6 files changed, 107 insertions(+), 76 deletions(-) create mode 100644 src/Perspex.SceneGraph/Media/ValidatingDrawingContext.cs diff --git a/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs b/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs index fd1f457a95..94fb19ea0b 100644 --- a/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs +++ b/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs @@ -101,7 +101,7 @@ namespace Perspex.Cairo.Media var intermediateSize = CalculateIntermediateSize(tileMode, targetSize, destinationRect.Size); using (var intermediate = new ImageSurface(Format.ARGB32, (int)intermediateSize.Width, (int)intermediateSize.Height)) - using (var context = new Context(intermediate)) + using (var ctx = new RenderTarget(intermediate).CreateDrawingContext()) { Rect drawRect; var transform = CalculateIntermediateTransform( @@ -111,12 +111,12 @@ namespace Perspex.Cairo.Media scale, translate, out drawRect); - var renderer = new RenderTarget(intermediate); - context.Rectangle(drawRect.ToCairo()); - context.Clip(); - context.Transform(transform.ToCairo()); - renderer.Render(visual, transform, drawRect); + using (ctx.PushClip(drawRect)) + using (ctx.PushTransform(transform)) + { + ctx.Render(visual); + } var result = new SurfacePattern(intermediate); diff --git a/src/Perspex.SceneGraph/Media/ValidatingDrawingContext.cs b/src/Perspex.SceneGraph/Media/ValidatingDrawingContext.cs new file mode 100644 index 0000000000..86ae342894 --- /dev/null +++ b/src/Perspex.SceneGraph/Media/ValidatingDrawingContext.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Reactive.Disposables; +using Perspex.Media.Imaging; + +namespace Perspex.Media +{ + public class ValidatingDrawingContext : IDrawingContext + { + private readonly IDrawingContext _base; + + public ValidatingDrawingContext(IDrawingContext @base) + { + _base = @base; + } + + public void Dispose() + { + _base.Dispose(); + } + + public Matrix CurrentTransform => _base.CurrentTransform; + public void DrawImage(IBitmap source, double opacity, Rect sourceRect, Rect destRect) + { + _base.DrawImage(source, opacity, sourceRect, destRect); + } + + public void DrawLine(Pen pen, Point p1, Point p2) + { + _base.DrawLine(pen, p1, p2); + } + + public void DrawGeometry(Brush brush, Pen pen, Geometry geometry) + { + _base.DrawGeometry(brush, pen, geometry); + } + + public void DrawRectangle(Pen pen, Rect rect, float cornerRadius = 0) + { + _base.DrawRectangle(pen, rect, cornerRadius); + } + + public void DrawText(Brush foreground, Point origin, FormattedText text) + { + _base.DrawText(foreground, origin, text); + } + + public void FillRectangle(Brush brush, Rect rect, float cornerRadius = 0) + { + _base.FillRectangle(brush, rect, cornerRadius); + } + + + Stack _stateStack = new Stack(); + + IDisposable Transform(IDisposable disposable) + { + _stateStack.Push(disposable); + return Disposable.Create(() => + { + var current = _stateStack.Peek(); + if (current != disposable) + throw new InvalidOperationException("Invalid push/pop order"); + current.Dispose(); + _stateStack.Pop(); + }); + } + + public IDisposable PushClip(Rect clip) => Transform(_base.PushClip(clip)); + + public IDisposable PushOpacity(double opacity) => Transform(_base.PushOpacity(opacity)); + + public IDisposable PushTransform(Matrix matrix) => Transform(_base.PushTransform(matrix)); + } +} \ No newline at end of file diff --git a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj index 7824b398e6..e09bed7d90 100644 --- a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj +++ b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj @@ -99,6 +99,7 @@ + diff --git a/src/Perspex.SceneGraph/Rendering/RendererBase.cs b/src/Perspex.SceneGraph/Rendering/RendererBase.cs index c9f79b2669..e43f458cf9 100644 --- a/src/Perspex.SceneGraph/Rendering/RendererBase.cs +++ b/src/Perspex.SceneGraph/Rendering/RendererBase.cs @@ -27,31 +27,7 @@ namespace Perspex.Rendering ctx.Render(visual); } - /// - /// Renders the specified visual. - /// - /// IRenderer instance - /// The visual to render. - /// The current translation. - /// The current transform. - public static void Render(this IRenderTarget renderTarget, IVisual visual, Matrix translation, Matrix transform) - { - using (var ctx = renderTarget.CreateDrawingContext()) - ctx.Render(visual, translation, transform); - } - /// - /// Renders the specified visual with the specified transform and clip. - /// - /// IRenderer instance - /// The visual to render. - /// The transform. - /// An optional clip rectangle. - public static void Render(this IRenderTarget renderTarget, IVisual visual, Matrix transform, Rect? clip = null) - { - using (var context = renderTarget.CreateDrawingContext()) - context.Render(visual, transform, clip); - } /// /// Renders the specified visual. @@ -60,65 +36,29 @@ namespace Perspex.Rendering /// /// The drawing context. public static void Render(this IDrawingContext context, IVisual visual) - { - context.Render(visual, Matrix.Identity); - } - - /// - /// Renders the specified visual with the specified transform and clip. - /// - /// The visual to render. - /// The drawing context. - /// The transform. - /// An optional clip rectangle. - public static void Render(this IDrawingContext context, IVisual visual, Matrix transform, Rect? clip = null) - { - using (clip.HasValue ? context.PushClip(clip.Value) : null) - { - context.Render(visual, Matrix.Identity, transform); - } - } - - /// - /// Renders the specified visual. - /// - /// The visual to render. - /// The drawing context. - /// The current translation. - /// The current transform. - public static void Render(this IDrawingContext context, IVisual visual, Matrix translation, Matrix transform) { var opacity = visual.Opacity; - if (visual.IsVisible && opacity > 0) { - // Translate any existing transform into this controls coordinate system. - Matrix offset = Matrix.CreateTranslation(visual.Bounds.Position); - transform = offset * transform * -offset; + var m = Matrix.CreateTranslation(visual.Bounds.Position); - // Update the current offset. - translation *= Matrix.CreateTranslation(visual.Bounds.Position); + var renderTransform = Matrix.Identity; - // Apply the control's render transform, if any. if (visual.RenderTransform != null) { - offset = Matrix.CreateTranslation(visual.TransformOrigin.ToPixels(visual.Bounds.Size)); - transform *= -offset * visual.RenderTransform.Value * offset; + var offset = -Matrix.CreateTranslation(visual.TransformOrigin.ToPixels(visual.Bounds.Size)); + renderTransform = offset*visual.RenderTransform.Value; } + m = context.CurrentTransform.Invert()*renderTransform*m*context.CurrentTransform; - // Draw the control and its children. - var m = transform * translation; - var d = context.PushTransform(m); - + using (context.PushTransform(m)) using (context.PushOpacity(opacity)) using (visual.ClipToBounds ? context.PushClip(new Rect(visual.Bounds.Size)) : null) { visual.Render(context); - d.Dispose(); - foreach (var child in visual.VisualChildren.OrderBy(x => x.ZIndex)) { - context.Render(child, translation, transform); + context.Render(child); } } } diff --git a/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs b/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs index c57c2b1477..ddb82fba19 100644 --- a/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs +++ b/src/Windows/Perspex.Direct2D1/Media/VisualBrushImpl.cs @@ -53,8 +53,12 @@ namespace Perspex.Direct2D1.Media out drawRect); var renderer = new RenderTarget(intermediate); - renderer.Render(visual, transform, drawRect); - + using (var ctx = renderer.CreateDrawingContext()) + using (ctx.PushClip(drawRect)) + using (ctx.PushTransform(transform)) + { + ctx.Render(visual); + } this.PlatformBrush = new BitmapBrush( target, intermediate.Bitmap, diff --git a/src/Windows/Perspex.Direct2D1/RenderTarget.cs b/src/Windows/Perspex.Direct2D1/RenderTarget.cs index ea6400be80..5feabdde87 100644 --- a/src/Windows/Perspex.Direct2D1/RenderTarget.cs +++ b/src/Windows/Perspex.Direct2D1/RenderTarget.cs @@ -91,13 +91,23 @@ namespace Perspex.Direct2D1 window.Resize(new Size2(width, height)); } + IDrawingContext Wrap(IDrawingContext ctx) + { +#if DEBUG + return new ValidatingDrawingContext(ctx); +#endif +#pragma warning disable 162 + return ctx; +#pragma warning restore 162 + } + /// /// Creates a drawing context for a rendering session. /// /// An . public IDrawingContext CreateDrawingContext() { - return new DrawingContext(_renderTarget, DirectWriteFactory); + return Wrap(new DrawingContext(_renderTarget, DirectWriteFactory)); } public void Dispose() From d03f5ce725d22457377a5ce44d6bac0d331f4146 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 18:06:08 +0300 Subject: [PATCH 17/28] Use context.Save/Restore --- src/Gtk/Perspex.Cairo/Media/DrawingContext.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs index 6987e5a19d..e55d75cc5c 100644 --- a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs +++ b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs @@ -4,6 +4,7 @@ using System; using System.Linq; using System.Reactive.Disposables; +using System.Runtime.InteropServices; using Perspex.Cairo.Media.Imaging; using Perspex.Media; @@ -200,6 +201,8 @@ namespace Perspex.Cairo.Media } } + private static Random Random = new Random(); + /// /// Pushes a clip rectange. /// @@ -207,10 +210,13 @@ namespace Perspex.Cairo.Media /// A disposable used to undo the clip rectangle. public IDisposable PushClip(Rect clip) { + _context.Save(); + uint fill = 0x90000000 | (unchecked((uint) Random.Next(int.MinValue, int.MaxValue))); + FillRectangle(new SolidColorBrush(fill), clip, 0); _context.Rectangle(clip.ToCairo()); _context.Clip(); - return Disposable.Create(() => _context.ResetClip()); + return Disposable.Create(() => _context.Restore()); } /// @@ -238,11 +244,12 @@ namespace Perspex.Cairo.Media /// A disposable used to undo the transformation. public IDisposable PushTransform(Matrix matrix) { + _context.Save(); _context.Transform(matrix.ToCairo()); return Disposable.Create(() => { - _context.Transform(matrix.Invert().ToCairo()); + _context.Restore(); }); } From a16afe187d9793bc2d0ca1c5dda9e8c89cabae5d Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 18:06:55 +0300 Subject: [PATCH 18/28] Removed debug code --- src/Gtk/Perspex.Cairo/Media/DrawingContext.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs index e55d75cc5c..f8c74f3f8f 100644 --- a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs +++ b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs @@ -211,8 +211,6 @@ namespace Perspex.Cairo.Media public IDisposable PushClip(Rect clip) { _context.Save(); - uint fill = 0x90000000 | (unchecked((uint) Random.Next(int.MinValue, int.MaxValue))); - FillRectangle(new SolidColorBrush(fill), clip, 0); _context.Rectangle(clip.ToCairo()); _context.Clip(); From 0592f3a0f10f160736d3f04cfbceb8e9594fecac Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 30 Sep 2015 18:59:24 +0200 Subject: [PATCH 19/28] Added some StackPanel tests. --- .../Perspex.Controls.UnitTests.csproj | 1 + .../StackPanelTests.cs | 150 ++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 tests/Perspex.Controls.UnitTests/StackPanelTests.cs diff --git a/tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj b/tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj index a41cec398c..29cd92b135 100644 --- a/tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj +++ b/tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj @@ -85,6 +85,7 @@ + diff --git a/tests/Perspex.Controls.UnitTests/StackPanelTests.cs b/tests/Perspex.Controls.UnitTests/StackPanelTests.cs new file mode 100644 index 0000000000..4b96aa3357 --- /dev/null +++ b/tests/Perspex.Controls.UnitTests/StackPanelTests.cs @@ -0,0 +1,150 @@ +// Copyright (c) The Perspex Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using Perspex.Controls; +using Xunit; + +namespace Perspex.Controls.UnitTests +{ + public class StackPanelTests + { + [Fact] + public void Lays_Out_Children_Vertically() + { + var target = new StackPanel + { + Children = new Controls + { + new Border { Height = 20, Width = 120 }, + new Border { Height = 30 }, + new Border { Height = 50 }, + } + }; + + target.Measure(Size.Infinity); + target.Arrange(new Rect(target.DesiredSize)); + + Assert.Equal(new Size(120, 100), target.Bounds.Size); + Assert.Equal(new Rect(0, 0, 120, 20), target.Children[0].Bounds); + Assert.Equal(new Rect(0, 20, 120, 30), target.Children[1].Bounds); + Assert.Equal(new Rect(0, 50, 120, 50), target.Children[2].Bounds); + } + + [Fact] + public void Lays_Out_Children_Horizontally() + { + var target = new StackPanel + { + Orientation = Orientation.Horizontal, + Children = new Controls + { + new Border { Width = 20, Height = 120 }, + new Border { Width = 30 }, + new Border { Width = 50 }, + } + }; + + target.Measure(Size.Infinity); + target.Arrange(new Rect(target.DesiredSize)); + + Assert.Equal(new Size(100, 120), target.Bounds.Size); + Assert.Equal(new Rect(0, 0, 20, 120), target.Children[0].Bounds); + Assert.Equal(new Rect(20, 0, 30, 120), target.Children[1].Bounds); + Assert.Equal(new Rect(50, 0, 50, 120), target.Children[2].Bounds); + } + + [Fact] + public void Lays_Out_Children_Vertically_With_Gap() + { + var target = new StackPanel + { + Gap = 10, + Children = new Controls + { + new Border { Height = 20, Width = 120 }, + new Border { Height = 30 }, + new Border { Height = 50 }, + } + }; + + target.Measure(Size.Infinity); + target.Arrange(new Rect(target.DesiredSize)); + + Assert.Equal(new Size(120, 130), target.Bounds.Size); + Assert.Equal(new Rect(0, 0, 120, 20), target.Children[0].Bounds); + Assert.Equal(new Rect(0, 30, 120, 30), target.Children[1].Bounds); + Assert.Equal(new Rect(0, 70, 120, 50), target.Children[2].Bounds); + } + + [Fact] + public void Lays_Out_Children_Horizontally_With_Gap() + { + var target = new StackPanel + { + Gap = 10, + Orientation = Orientation.Horizontal, + Children = new Controls + { + new Border { Width = 20, Height = 120 }, + new Border { Width = 30 }, + new Border { Width = 50 }, + } + }; + + target.Measure(Size.Infinity); + target.Arrange(new Rect(target.DesiredSize)); + + Assert.Equal(new Size(130, 120), target.Bounds.Size); + Assert.Equal(new Rect(0, 0, 20, 120), target.Children[0].Bounds); + Assert.Equal(new Rect(30, 0, 30, 120), target.Children[1].Bounds); + Assert.Equal(new Rect(70, 0, 50, 120), target.Children[2].Bounds); + } + + [Fact] + public void Lays_Out_Children_Vertically_Even_If_Larger_Than_Panel() + { + var target = new StackPanel + { + Height = 60, + Children = new Controls + { + new Border { Height = 20, Width = 120 }, + new Border { Height = 30 }, + new Border { Height = 50 }, + } + }; + + target.Measure(Size.Infinity); + target.Arrange(new Rect(target.DesiredSize)); + + Assert.Equal(new Size(120, 60), target.Bounds.Size); + Assert.Equal(new Rect(0, 0, 120, 20), target.Children[0].Bounds); + Assert.Equal(new Rect(0, 20, 120, 30), target.Children[1].Bounds); + Assert.Equal(new Rect(0, 50, 120, 50), target.Children[2].Bounds); + } + + [Fact] + public void Lays_Out_Children_Horizontally_Even_If_Larger_Than_Panel() + { + var target = new StackPanel + { + Width = 60, + Orientation = Orientation.Horizontal, + Children = new Controls + { + new Border { Width = 20, Height = 120 }, + new Border { Width = 30 }, + new Border { Width = 50 }, + } + }; + + target.Measure(Size.Infinity); + target.Arrange(new Rect(target.DesiredSize)); + + Assert.Equal(new Size(60, 120), target.Bounds.Size); + Assert.Equal(new Rect(0, 0, 20, 120), target.Children[0].Bounds); + Assert.Equal(new Rect(20, 0, 30, 120), target.Children[1].Bounds); + Assert.Equal(new Rect(50, 0, 50, 120), target.Children[2].Bounds); + } + } +} From 991b7058af41a1cab5113b4f3d7543594bec945f Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 30 Sep 2015 19:02:34 +0200 Subject: [PATCH 20/28] Clip Panel content to bounds. --- src/Perspex.Controls/Panel.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Perspex.Controls/Panel.cs b/src/Perspex.Controls/Panel.cs index 76bac0c51f..5e0c83982b 100644 --- a/src/Perspex.Controls/Panel.cs +++ b/src/Perspex.Controls/Panel.cs @@ -29,6 +29,14 @@ namespace Perspex.Controls private ILogical _childLogicalParent; + /// + /// Initializes static members of the class. + /// + static Panel() + { + ClipToBoundsProperty.OverrideDefaultValue(true); + } + /// /// Initializes a new instance of the class. /// From 45e17d148287518d09e03228f1f8166f773c8577 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 20:17:15 +0300 Subject: [PATCH 21/28] Fixed Border_Nested_Rotate --- src/Perspex.SceneGraph/Rendering/RendererBase.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Perspex.SceneGraph/Rendering/RendererBase.cs b/src/Perspex.SceneGraph/Rendering/RendererBase.cs index e43f458cf9..ba4a0d35c1 100644 --- a/src/Perspex.SceneGraph/Rendering/RendererBase.cs +++ b/src/Perspex.SceneGraph/Rendering/RendererBase.cs @@ -46,8 +46,9 @@ namespace Perspex.Rendering if (visual.RenderTransform != null) { - var offset = -Matrix.CreateTranslation(visual.TransformOrigin.ToPixels(visual.Bounds.Size)); - renderTransform = offset*visual.RenderTransform.Value; + var origin = visual.TransformOrigin.ToPixels(new Size(visual.Bounds.Width, visual.Bounds.Height)); + var offset = Matrix.CreateTranslation(origin); + renderTransform = (-offset)*visual.RenderTransform.Value*(offset); } m = context.CurrentTransform.Invert()*renderTransform*m*context.CurrentTransform; From 862e9113b45007e8b7498683f2cdb151f1568ff3 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 30 Sep 2015 19:18:25 +0200 Subject: [PATCH 22/28] Fixed the TextBox template. Previous change to add floating watermark had broken vertical scrolling. --- src/Perspex.Themes.Default/TextBoxStyle.cs | 52 +++++++++++----------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/Perspex.Themes.Default/TextBoxStyle.cs b/src/Perspex.Themes.Default/TextBoxStyle.cs index 7f72c68c3f..82a2519469 100644 --- a/src/Perspex.Themes.Default/TextBoxStyle.cs +++ b/src/Perspex.Themes.Default/TextBoxStyle.cs @@ -60,35 +60,35 @@ namespace Perspex.Themes.Default [~Border.BorderBrushProperty] = control[~TemplatedControl.BorderBrushProperty], [~Border.BorderThicknessProperty] = control[~TemplatedControl.BorderThicknessProperty], - Child = new StackPanel + Child = new ScrollViewer { - Children = new Controls.Controls + [~ScrollViewer.CanScrollHorizontallyProperty] = control[~ScrollViewer.CanScrollHorizontallyProperty], + [~ScrollViewer.HorizontalScrollBarVisibilityProperty] = control[~ScrollViewer.HorizontalScrollBarVisibilityProperty], + [~ScrollViewer.VerticalScrollBarVisibilityProperty] = control[~ScrollViewer.VerticalScrollBarVisibilityProperty], + Content = new StackPanel { - new TextBlock + Children = new Controls.Controls { - Name = "floatingWatermark", - Foreground = SolidColorBrush.Parse("#007ACC"), - FontSize = 10, - [~TextBlock.TextProperty] = control[~TextBox.WatermarkProperty], - [~TextBlock.IsVisibleProperty] = control[~TextBox.TextProperty].Cast().Select(x => (object)(!string.IsNullOrEmpty(x) && control.UseFloatingWatermark)) - }, - new Panel - { - Children = new Controls.Controls + new TextBlock { - new TextBlock - { - Name = "watermark", - Opacity = 0.5, - [~TextBlock.TextProperty] = control[~TextBox.WatermarkProperty], - [~TextBlock.IsVisibleProperty] = control[~TextBox.TextProperty].Cast().Select(x => (object)string.IsNullOrEmpty(x)) - }, - new ScrollViewer + Name = "floatingWatermark", + Foreground = SolidColorBrush.Parse("#007ACC"), + FontSize = 10, + [~TextBlock.TextProperty] = control[~TextBox.WatermarkProperty], + [~TextBlock.IsVisibleProperty] = control[~TextBox.TextProperty].Cast().Select(x => (object)(!string.IsNullOrEmpty(x) && control.UseFloatingWatermark)) + }, + new Panel + { + Children = new Controls.Controls { - [~ScrollViewer.CanScrollHorizontallyProperty] = control[~ScrollViewer.CanScrollHorizontallyProperty], - [~ScrollViewer.HorizontalScrollBarVisibilityProperty] = control[~ScrollViewer.HorizontalScrollBarVisibilityProperty], - [~ScrollViewer.VerticalScrollBarVisibilityProperty] = control[~ScrollViewer.VerticalScrollBarVisibilityProperty], - Content = new TextPresenter + new TextBlock + { + Name = "watermark", + Opacity = 0.5, + [~TextBlock.TextProperty] = control[~TextBox.WatermarkProperty], + [~TextBlock.IsVisibleProperty] = control[~TextBox.TextProperty].Cast().Select(x => (object)string.IsNullOrEmpty(x)) + }, + new TextPresenter { Name = "textPresenter", [~TextPresenter.CaretIndexProperty] = control[~TextBox.CaretIndexProperty], @@ -99,9 +99,9 @@ namespace Perspex.Themes.Default } } } - } + } } - }, + } }; return result; From e8406b3f2708a43c7b899d22186cdee298a48ad0 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 20:27:56 +0300 Subject: [PATCH 23/28] Fixed animations tab --- samples/TestApplication/Program.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/TestApplication/Program.cs b/samples/TestApplication/Program.cs index 90bb76905d..530782e695 100644 --- a/samples/TestApplication/Program.cs +++ b/samples/TestApplication/Program.cs @@ -742,6 +742,7 @@ namespace TestApplication VerticalAlignment = VerticalAlignment.Top, Gap = 4, Margin = new Thickness(10), + ClipToBounds = false, Children = new Controls { new TextBlock From d9ca9c2624c09267752a74f1eb7c06786d4a0c28 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 30 Sep 2015 19:35:44 +0200 Subject: [PATCH 24/28] Override ClipToBounds on correct control. --- src/Perspex.Controls/Panel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Perspex.Controls/Panel.cs b/src/Perspex.Controls/Panel.cs index 5e0c83982b..08e6621adb 100644 --- a/src/Perspex.Controls/Panel.cs +++ b/src/Perspex.Controls/Panel.cs @@ -34,7 +34,7 @@ namespace Perspex.Controls /// static Panel() { - ClipToBoundsProperty.OverrideDefaultValue(true); + ClipToBoundsProperty.OverrideDefaultValue(true); } /// From c91ea908da2f1b3c8b2e9f292e04912fc89c4954 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 30 Sep 2015 19:38:08 +0200 Subject: [PATCH 25/28] Fixed Animations page again. --- samples/TestApplication/Program.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/samples/TestApplication/Program.cs b/samples/TestApplication/Program.cs index 530782e695..0b8a6134c7 100644 --- a/samples/TestApplication/Program.cs +++ b/samples/TestApplication/Program.cs @@ -737,12 +737,9 @@ namespace TestApplication Header = "Animations", Content = new StackPanel { - HorizontalAlignment = HorizontalAlignment.Left, Orientation = Orientation.Vertical, - VerticalAlignment = VerticalAlignment.Top, Gap = 4, Margin = new Thickness(10), - ClipToBounds = false, Children = new Controls { new TextBlock @@ -768,6 +765,7 @@ namespace TestApplication }), new Canvas { + ClipToBounds = false, Children = new Controls { (border1 = new Border From 0cc553f69e5c73a0436c2348b9bd3bd3bced6d98 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 23:23:30 +0300 Subject: [PATCH 26/28] Added mouse wheel support to GTK backend --- src/Gtk/Perspex.Gtk/WindowImpl.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Gtk/Perspex.Gtk/WindowImpl.cs b/src/Gtk/Perspex.Gtk/WindowImpl.cs index 7b4b149dc3..503ca9266a 100644 --- a/src/Gtk/Perspex.Gtk/WindowImpl.cs +++ b/src/Gtk/Perspex.Gtk/WindowImpl.cs @@ -167,6 +167,23 @@ namespace Perspex.Gtk return true; } + protected override bool OnScrollEvent(EventScroll evnt) + { + double step = 1; + var delta = new Vector(); + if (evnt.Direction == ScrollDirection.Down) + delta = new Vector(0, -step); + else if (evnt.Direction == ScrollDirection.Up) + delta = new Vector(0, step); + else if (evnt.Direction == ScrollDirection.Right) + delta = new Vector(-step, 0); + if (evnt.Direction == ScrollDirection.Left) + delta = new Vector(step, 0); + var e = new RawMouseWheelEventArgs(GtkMouseDevice.Instance, evnt.Time, _inputRoot, new Point(evnt.X, evnt.Y), delta, GetModifierKeys(evnt.State)); + Input(e); + return base.OnScrollEvent(evnt); + } + protected override bool OnButtonReleaseEvent(EventButton evnt) { var e = new RawMouseEventArgs( From b016c8d34db89e7d4608f5d06b801cf4a60c5563 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 23:50:55 +0300 Subject: [PATCH 27/28] Moved some stuff from XamlTestApplication to XamlTestApplicationPcl --- Perspex.sln | 7 + .../XamlTestApplication.csproj | 14 +- .../MainViewModel.cs | 0 .../Properties/AssemblyInfo.cs | 30 +++++ .../Views/MainWindow.cs | 0 .../Views/MainWindow.paml | 0 .../XamlTestApplicationPcl.csproj | 127 ++++++++++++++++++ .../github_icon.png | Bin .../XamlTestApplicationPcl/packages.config | 4 + 9 files changed, 172 insertions(+), 10 deletions(-) rename samples/{XamlTestApplication => XamlTestApplicationPcl}/MainViewModel.cs (100%) create mode 100644 samples/XamlTestApplicationPcl/Properties/AssemblyInfo.cs rename samples/{XamlTestApplication => XamlTestApplicationPcl}/Views/MainWindow.cs (100%) rename samples/{XamlTestApplication => XamlTestApplicationPcl}/Views/MainWindow.paml (100%) create mode 100644 samples/XamlTestApplicationPcl/XamlTestApplicationPcl.csproj rename samples/{XamlTestApplication => XamlTestApplicationPcl}/github_icon.png (100%) create mode 100644 samples/XamlTestApplicationPcl/packages.config diff --git a/Perspex.sln b/Perspex.sln index 22b196d2c8..f9f2f0a09f 100644 --- a/Perspex.sln +++ b/Perspex.sln @@ -96,6 +96,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.HtmlRenderer", "src EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "PlatformSupport", "src\Shared\PlatformSupport\PlatformSupport.shproj", "{E4D9629C-F168-4224-3F51-A5E482FFBC42}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlTestApplicationPcl", "samples\XamlTestApplicationPcl\XamlTestApplicationPcl.csproj", "{EA113F1A-D8D7-4142-9948-353270E7EBAE}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution src\Shared\PlatformSupport\PlatformSupport.projitems*{e4d9629c-f168-4224-3f51-a5e482ffbc42}*SharedItemsImports = 13 @@ -235,6 +237,10 @@ Global {5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}.Debug|Any CPU.Build.0 = Debug|Any CPU {5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}.Release|Any CPU.ActiveCfg = Release|Any CPU {5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}.Release|Any CPU.Build.0 = Release|Any CPU + {EA113F1A-D8D7-4142-9948-353270E7EBAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EA113F1A-D8D7-4142-9948-353270E7EBAE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EA113F1A-D8D7-4142-9948-353270E7EBAE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EA113F1A-D8D7-4142-9948-353270E7EBAE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -260,5 +266,6 @@ Global {54F237D5-A70A-4752-9656-0C70B1A7B047} = {B9894058-278A-46B5-B6ED-AD613FCC03B3} {FB05AC90-89BA-4F2F-A924-F37875FB547C} = {B9894058-278A-46B5-B6ED-AD613FCC03B3} {E4D9629C-F168-4224-3F51-A5E482FFBC42} = {A689DEF5-D50F-4975-8B72-124C9EB54066} + {EA113F1A-D8D7-4142-9948-353270E7EBAE} = {9B9E3891-2366-4253-A952-D08BCEB71098} EndGlobalSection EndGlobal diff --git a/samples/XamlTestApplication/XamlTestApplication.csproj b/samples/XamlTestApplication/XamlTestApplication.csproj index d70e2e3297..d384db9372 100644 --- a/samples/XamlTestApplication/XamlTestApplication.csproj +++ b/samples/XamlTestApplication/XamlTestApplication.csproj @@ -77,10 +77,8 @@ - - @@ -146,17 +144,13 @@ {811A76CF-1CF6-440F-963B-BBE31BD72A82} Perspex.Win32 - - - - PreserveNewest - + + {ea113f1a-d8d7-4142-9948-353270e7ebae} + XamlTestApplicationPcl + - - Designer - diff --git a/samples/XamlTestApplication/MainViewModel.cs b/samples/XamlTestApplicationPcl/MainViewModel.cs similarity index 100% rename from samples/XamlTestApplication/MainViewModel.cs rename to samples/XamlTestApplicationPcl/MainViewModel.cs diff --git a/samples/XamlTestApplicationPcl/Properties/AssemblyInfo.cs b/samples/XamlTestApplicationPcl/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..3614e93d10 --- /dev/null +++ b/samples/XamlTestApplicationPcl/Properties/AssemblyInfo.cs @@ -0,0 +1,30 @@ +using System.Resources; +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("XamlTestApplicationPcl")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("XamlTestApplicationPcl")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: NeutralResourcesLanguage("en")] + +// 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")] diff --git a/samples/XamlTestApplication/Views/MainWindow.cs b/samples/XamlTestApplicationPcl/Views/MainWindow.cs similarity index 100% rename from samples/XamlTestApplication/Views/MainWindow.cs rename to samples/XamlTestApplicationPcl/Views/MainWindow.cs diff --git a/samples/XamlTestApplication/Views/MainWindow.paml b/samples/XamlTestApplicationPcl/Views/MainWindow.paml similarity index 100% rename from samples/XamlTestApplication/Views/MainWindow.paml rename to samples/XamlTestApplicationPcl/Views/MainWindow.paml diff --git a/samples/XamlTestApplicationPcl/XamlTestApplicationPcl.csproj b/samples/XamlTestApplicationPcl/XamlTestApplicationPcl.csproj new file mode 100644 index 0000000000..6b8cc8ed1f --- /dev/null +++ b/samples/XamlTestApplicationPcl/XamlTestApplicationPcl.csproj @@ -0,0 +1,127 @@ + + + + + 10.0 + Debug + AnyCPU + {EA113F1A-D8D7-4142-9948-353270E7EBAE} + Library + Properties + XamlTestApplication + XamlTestApplicationPcl + en-US + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Profile7 + v4.5 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + Designer + + + + + + + + + + PreserveNewest + + + + + {3e53a01a-b331-47f3-b828-4a5717e77a24} + Perspex.Markup.Xaml + + + {d211e587-d8bc-45b9-95a4-f297c8fa5200} + Perspex.Animation + + + {799a7bb5-3c2c-48b6-85a7-406a12c420da} + Perspex.Application + + + {b09b78d8-9b26-48b0-9149-d64a2f120f3f} + Perspex.Base + + + {d2221c82-4a25-4583-9b43-d791e3f6820c} + Perspex.Controls + + + {7062ae20-5dcc-4442-9645-8195bdece63e} + Perspex.Diagnostics + + + {5fb2b005-0a7f-4dad-add4-3ed01444e63d} + Perspex.HtmlRenderer + + + {62024b2d-53eb-4638-b26b-85eeaa54866e} + Perspex.Input + + + {6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b} + Perspex.Interactivity + + + {42472427-4774-4c81-8aff-9f27b8e31721} + Perspex.Layout + + + {6417b24e-49c2-4985-8db2-3ab9d898ec91} + Perspex.ReactiveUI + + + {eb582467-6abb-43a1-b052-e981ba910e3a} + Perspex.SceneGraph + + + {f1baa01a-f176-4c6a-b39d-5b40bb1b148f} + Perspex.Styling + + + {3e10a5fa-e8da-48b1-ad44-6a5b6cb7750f} + Perspex.Themes.Default + + + + + ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll + True + + + + + + + + \ No newline at end of file diff --git a/samples/XamlTestApplication/github_icon.png b/samples/XamlTestApplicationPcl/github_icon.png similarity index 100% rename from samples/XamlTestApplication/github_icon.png rename to samples/XamlTestApplicationPcl/github_icon.png diff --git a/samples/XamlTestApplicationPcl/packages.config b/samples/XamlTestApplicationPcl/packages.config new file mode 100644 index 0000000000..2115574cc5 --- /dev/null +++ b/samples/XamlTestApplicationPcl/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From 01562bd98c20fec2608fcdc70c5e0cbed5a81c8b Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 30 Sep 2015 23:59:06 +0300 Subject: [PATCH 28/28] XamlTestApp code cleanup --- samples/XamlTestApplication/App.cs | 6 +-- samples/XamlTestApplication/Program.cs | 30 +---------- .../XamlTestApplicationPcl/MainViewModel.cs | 52 ------------------- samples/XamlTestApplicationPcl/XamlTestApp.cs | 22 ++++++++ .../XamlTestApplicationPcl.csproj | 2 +- 5 files changed, 27 insertions(+), 85 deletions(-) delete mode 100644 samples/XamlTestApplicationPcl/MainViewModel.cs create mode 100644 samples/XamlTestApplicationPcl/XamlTestApp.cs diff --git a/samples/XamlTestApplication/App.cs b/samples/XamlTestApplication/App.cs index d0c6f59040..463d6ecebf 100644 --- a/samples/XamlTestApplication/App.cs +++ b/samples/XamlTestApplication/App.cs @@ -7,13 +7,11 @@ using Perspex.Themes.Default; namespace XamlTestApplication { - public class App : Application + public class App : XamlTestApp { - public App() + protected override void RegisterPlatform() { - RegisterServices(); InitializeSubsystems((int)Environment.OSVersion.Platform); - Styles = new DefaultTheme(); } } } diff --git a/samples/XamlTestApplication/Program.cs b/samples/XamlTestApplication/Program.cs index d115b67809..e9421802bf 100644 --- a/samples/XamlTestApplication/Program.cs +++ b/samples/XamlTestApplication/Program.cs @@ -13,23 +13,6 @@ using XamlTestApplication.Views; namespace XamlTestApplication { - internal class Item - { - public string Name { get; set; } - public string Value { get; set; } - } - - internal class Node - { - public Node() - { - Children = new PerspexList(); - } - - public string Name { get; set; } - public PerspexList Children { get; set; } - } - internal class Program { private static void Main() @@ -38,18 +21,9 @@ namespace XamlTestApplication App application = new App { - DataTemplates = new DataTemplates - { - new TreeDataTemplate( - x => new TextBlock { Text = x.Name }, - x => x.Children, - x => true), - }, - }; - - var testCommand = ReactiveCommand.Create(); - testCommand.Subscribe(_ => Debug.WriteLine("Test command executed.")); + }; + var window = new MainWindow(); window.Show(); Application.Current.Run(window); diff --git a/samples/XamlTestApplicationPcl/MainViewModel.cs b/samples/XamlTestApplicationPcl/MainViewModel.cs deleted file mode 100644 index 450c8f422f..0000000000 --- a/samples/XamlTestApplicationPcl/MainViewModel.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) The Perspex Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System.Collections.Generic; -using ReactiveUI; - -namespace XamlTestApplication -{ - public class MainViewModel : ReactiveObject - { - private string _name; - - public MainViewModel() - { - Name = "Jos\u00E9 Manuel"; - People = new List - { - new Person("a little bit of Monica in my life"), - new Person("a little bit of Erica by my side"), - new Person("a little bit of Rita is all I need"), - new Person("a little bit of Tina is what I see"), - new Person("a little bit of Sandra in the sun"), - new Person("a little bit of Mary all night long"), - new Person("a little bit of Jessica here I am"), - }; - } - - public string Name - { - get { return _name; } - set { this.RaiseAndSetIfChanged(ref _name, value); } - } - - public List People { get; set; } - } - - public class Person - { - private string _name; - - public Person(string name) - { - _name = name; - } - - public string Name - { - get { return _name; } - set { _name = value; } - } - } -} \ No newline at end of file diff --git a/samples/XamlTestApplicationPcl/XamlTestApp.cs b/samples/XamlTestApplicationPcl/XamlTestApp.cs new file mode 100644 index 0000000000..5683213631 --- /dev/null +++ b/samples/XamlTestApplicationPcl/XamlTestApp.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Perspex; +using Perspex.Themes.Default; + +namespace XamlTestApplication +{ + public abstract class XamlTestApp : Application + { + protected abstract void RegisterPlatform(); + + public XamlTestApp() + { + RegisterServices(); + RegisterPlatform(); + Styles = new DefaultTheme(); + } + } +} diff --git a/samples/XamlTestApplicationPcl/XamlTestApplicationPcl.csproj b/samples/XamlTestApplicationPcl/XamlTestApplicationPcl.csproj index 6b8cc8ed1f..fcc0fdcc27 100644 --- a/samples/XamlTestApplicationPcl/XamlTestApplicationPcl.csproj +++ b/samples/XamlTestApplicationPcl/XamlTestApplicationPcl.csproj @@ -40,9 +40,9 @@ - +