From 6d45c57dbb594202cdf04051ce7ada249e95f240 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Mon, 15 Dec 2014 20:00:25 +0100 Subject: [PATCH] Added simple animation. --- .../Presenters/ScrollContentPresenter.cs | 1 + Perspex.Controls/Window.cs | 12 ++---- Perspex.SceneGraph/IVisual.cs | 5 +++ Perspex.SceneGraph/Media/ITransform.cs | 4 ++ Perspex.SceneGraph/Media/MatrixTransform.cs | 4 ++ Perspex.SceneGraph/Media/RotateTransform.cs | 4 ++ Perspex.SceneGraph/Media/Transform.cs | 12 ++++++ Perspex.SceneGraph/Visual.cs | 39 +++++++++++++++++ TestApplication/Program.cs | 43 ++++++++++++++++++- Windows/Perspex.Direct2D1/Renderer.cs | 2 +- Windows/Perspex.Win32/WindowImpl.cs | 2 - 11 files changed, 115 insertions(+), 13 deletions(-) diff --git a/Perspex.Controls/Presenters/ScrollContentPresenter.cs b/Perspex.Controls/Presenters/ScrollContentPresenter.cs index 4e4cb776bb..5b93e5d41c 100644 --- a/Perspex.Controls/Presenters/ScrollContentPresenter.cs +++ b/Perspex.Controls/Presenters/ScrollContentPresenter.cs @@ -31,6 +31,7 @@ namespace Perspex.Controls.Presenters static ScrollContentPresenter() { + ClipToBoundsProperty.OverrideDefaultValue(typeof(ScrollContentPresenter), true); Control.AffectsArrange(OffsetProperty); } diff --git a/Perspex.Controls/Window.cs b/Perspex.Controls/Window.cs index 1c8b4eb33c..0f6494fc82 100644 --- a/Perspex.Controls/Window.cs +++ b/Perspex.Controls/Window.cs @@ -164,7 +164,9 @@ namespace Perspex.Controls private void HandleRenderNeeded() { - this.dispatcher.InvokeAsync(this.RenderVisualTree, DispatcherPriority.Render); + this.dispatcher.InvokeAsync( + () => this.impl.Invalidate(new Rect(this.ClientSize)), + DispatcherPriority.Render); } private void HandlePaint(Rect rect, IPlatformHandle handle) @@ -186,13 +188,5 @@ namespace Perspex.Controls this.LayoutManager.ExecuteLayoutPass(); this.impl.Invalidate(new Rect(this.ClientSize)); } - - private void RenderVisualTree() - { - if (!this.LayoutManager.LayoutQueued) - { - this.impl.Invalidate(new Rect(this.ClientSize)); - } - } } } diff --git a/Perspex.SceneGraph/IVisual.cs b/Perspex.SceneGraph/IVisual.cs index 5688c796bb..1f1aa8775a 100644 --- a/Perspex.SceneGraph/IVisual.cs +++ b/Perspex.SceneGraph/IVisual.cs @@ -28,6 +28,11 @@ namespace Perspex /// Rect Bounds { get; } + /// + /// Gets a value indicating whether the scene graph node should be clipped to its bounds. + /// + bool ClipToBounds { get; } + /// /// Gets a value indicating whether this scene graph node is visible. /// diff --git a/Perspex.SceneGraph/Media/ITransform.cs b/Perspex.SceneGraph/Media/ITransform.cs index 198c0c1392..248063d6ec 100644 --- a/Perspex.SceneGraph/Media/ITransform.cs +++ b/Perspex.SceneGraph/Media/ITransform.cs @@ -6,8 +6,12 @@ namespace Perspex.Media { + using System; + public interface ITransform { + event EventHandler Changed; + Matrix Value { get; } } } diff --git a/Perspex.SceneGraph/Media/MatrixTransform.cs b/Perspex.SceneGraph/Media/MatrixTransform.cs index 4db9b26ec0..af9373ab4a 100644 --- a/Perspex.SceneGraph/Media/MatrixTransform.cs +++ b/Perspex.SceneGraph/Media/MatrixTransform.cs @@ -6,6 +6,8 @@ namespace Perspex.Media { + using System; + public class MatrixTransform : Transform { public static readonly PerspexProperty MatrixProperty = @@ -13,9 +15,11 @@ namespace Perspex.Media public MatrixTransform() { + this.GetObservable(MatrixProperty).Subscribe(_ => this.RaiseChanged()); } public MatrixTransform(Matrix matrix) + : this() { this.Matrix = matrix; } diff --git a/Perspex.SceneGraph/Media/RotateTransform.cs b/Perspex.SceneGraph/Media/RotateTransform.cs index 67fe38b7b8..8759df0bdb 100644 --- a/Perspex.SceneGraph/Media/RotateTransform.cs +++ b/Perspex.SceneGraph/Media/RotateTransform.cs @@ -6,6 +6,8 @@ namespace Perspex.Media { + using System; + public class RotateTransform : Transform { public static readonly PerspexProperty AngleProperty = @@ -13,9 +15,11 @@ namespace Perspex.Media public RotateTransform() { + this.GetObservable(AngleProperty).Subscribe(_ => this.RaiseChanged()); } public RotateTransform(double angle) + : this() { this.Angle = angle; } diff --git a/Perspex.SceneGraph/Media/Transform.cs b/Perspex.SceneGraph/Media/Transform.cs index 437e018b65..0f8ba46c5c 100644 --- a/Perspex.SceneGraph/Media/Transform.cs +++ b/Perspex.SceneGraph/Media/Transform.cs @@ -6,8 +6,20 @@ namespace Perspex.Media { + using System; + public abstract class Transform : PerspexObject, ITransform { + public event EventHandler Changed; + public abstract Matrix Value { get; } + + protected void RaiseChanged() + { + if (this.Changed != null) + { + this.Changed(this, EventArgs.Empty); + } + } } } diff --git a/Perspex.SceneGraph/Visual.cs b/Perspex.SceneGraph/Visual.cs index 2e5238dcf4..d4a0d67228 100644 --- a/Perspex.SceneGraph/Visual.cs +++ b/Perspex.SceneGraph/Visual.cs @@ -10,12 +10,16 @@ namespace Perspex using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; + using System.Reactive.Linq; using Perspex.Media; using Perspex.Rendering; using Splat; public class Visual : PerspexObject, IVisual { + public static readonly PerspexProperty ClipToBoundsProperty = + PerspexProperty.Register("ClipToBounds"); + public static readonly PerspexProperty IsVisibleProperty = PerspexProperty.Register("IsVisible", true); @@ -37,6 +41,7 @@ namespace Perspex static Visual() { AffectsRender(IsVisibleProperty); + RenderTransformProperty.Changed.Subscribe(RenderTransformChanged); } public Visual() @@ -45,6 +50,12 @@ namespace Perspex this.visualChildren.CollectionChanged += this.VisualChildrenChanged; } + public bool ClipToBounds + { + get { return this.GetValue(ClipToBoundsProperty); } + set { this.SetValue(ClipToBoundsProperty, value); } + } + public bool IsVisible { get { return this.GetValue(IsVisibleProperty); } @@ -197,6 +208,34 @@ namespace Perspex return result; } + private static void RenderTransformChanged(PerspexPropertyChangedEventArgs e) + { + var sender = e.Sender as Visual; + + if (sender != null) + { + var oldValue = e.OldValue as ITransform; + var newValue = e.NewValue as ITransform; + + if (oldValue != null) + { + oldValue.Changed -= sender.RenderTransformChanged; + } + + if (newValue != null) + { + newValue.Changed += sender.RenderTransformChanged; + } + + sender.InvalidateVisual(); + } + } + + private void RenderTransformChanged(object sender, EventArgs e) + { + this.InvalidateVisual(); + } + private void SetVisualParent(Visual value) { if (this.visualParent != value) diff --git a/TestApplication/Program.cs b/TestApplication/Program.cs index a5f402aa37..a70d2ab273 100644 --- a/TestApplication/Program.cs +++ b/TestApplication/Program.cs @@ -1,7 +1,9 @@ -using System.Reactive.Linq; +using System; +using System.Reactive.Linq; using Perspex; using Perspex.Controls; using Perspex.Controls.Primitives; +using Perspex.Controls.Shapes; using Perspex.Diagnostics; using Perspex.Layout; using Perspex.Media; @@ -132,6 +134,7 @@ namespace TestApplication ListsTab(), SlidersTab(), LayoutTab(), + AnimationsTab(), } }, new TextBlock @@ -430,5 +433,43 @@ namespace TestApplication } }; } + + private static TabItem AnimationsTab() + { + Rectangle rect1; + + var result = new TabItem + { + Header = "Animations", + Content = new Grid + { + ColumnDefinitions = new ColumnDefinitions + { + new ColumnDefinition(1, GridUnitType.Star), + }, + Children = new Controls + { + (rect1 = new Rectangle + { + Width = 100, + Height = 100, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + Fill = Brushes.Crimson, + RenderTransform = new RotateTransform(), + }), + }, + }, + }; + + Observable.Interval(TimeSpan.FromMilliseconds(10)) + .Subscribe(x => + { + ((RotateTransform)rect1.RenderTransform).Angle = x; + }); + + return result; + } + } } diff --git a/Windows/Perspex.Direct2D1/Renderer.cs b/Windows/Perspex.Direct2D1/Renderer.cs index 41b26588a7..fc6e5bbce8 100644 --- a/Windows/Perspex.Direct2D1/Renderer.cs +++ b/Windows/Perspex.Direct2D1/Renderer.cs @@ -133,7 +133,7 @@ namespace Perspex.Direct2D1 transform *= Matrix.Translation(visual.Bounds.Position); - using (context.PushClip(visual.Bounds)) + using (visual.ClipToBounds ? context.PushClip(visual.Bounds) : null) using (context.PushTransform(transform)) { visual.Render(context); diff --git a/Windows/Perspex.Win32/WindowImpl.cs b/Windows/Perspex.Win32/WindowImpl.cs index bd191b7e4a..97f12c3b27 100644 --- a/Windows/Perspex.Win32/WindowImpl.cs +++ b/Windows/Perspex.Win32/WindowImpl.cs @@ -103,8 +103,6 @@ namespace Perspex.Win32 lpszClassName = this.className, }; - System.Diagnostics.Debug.WriteLine("Registered class " + this.className); - ushort atom = UnmanagedMethods.RegisterClassEx(ref wndClassEx); if (atom == 0)