Browse Source

Implemented transform containers

pull/241/head
Nikita Tsukanov 11 years ago
parent
commit
8a2578a985
  1. 56
      src/Perspex.SceneGraph/Media/DrawingContext.cs
  2. 4
      src/Perspex.SceneGraph/Rendering/RendererBase.cs

56
src/Perspex.SceneGraph/Media/DrawingContext.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -12,15 +13,42 @@ namespace Perspex.Media
private readonly IDrawingContextImpl _impl;
private int _currentLevel;
private Stack<TransformContainer> _transformContainers = new Stack<TransformContainer>();
struct TransformContainer
{
public Matrix LocalTransform;
public Matrix ContainerTransform;
public TransformContainer(Matrix localTransform, Matrix containerTransform)
{
LocalTransform = localTransform;
ContainerTransform = containerTransform;
}
}
public DrawingContext(IDrawingContextImpl impl)
{
_impl = impl;
}
private Matrix _currentTransform = Matrix.Identity;
/// <summary>
/// Gets the current transform of the drawing context.
/// </summary>
public Matrix CurrentTransform => _impl.Transform;
public Matrix CurrentTransform
{
get { return _currentTransform; }
private set
{
_currentTransform = value;
_impl.Transform = _currentTransform*_currentContainerTransform;
}
}
private Matrix _currentContainerTransform = Matrix.Identity;
/// <summary>
/// Draws a bitmap image.
@ -87,7 +115,8 @@ namespace Perspex.Media
None,
Matrix,
Opacity,
Clip
Clip,
MatrixContainer
}
public PushedState(DrawingContext context, PushedStateType type, Matrix matrix = default(Matrix))
@ -107,15 +136,18 @@ namespace Perspex.Media
throw new InvalidOperationException("Wrong Push/Pop state order");
_context._currentLevel--;
if (_type == PushedStateType.Matrix)
_context._impl.Transform = _matrix;
_context.CurrentTransform = _matrix;
else if(_type == PushedStateType.Clip)
_context._impl.PopClip();
else if(_type == PushedStateType.Opacity)
_context._impl.PopOpacity();
else if (_type == PushedStateType.MatrixContainer)
{
var cont = _context._transformContainers.Pop();
_context._currentContainerTransform = cont.ContainerTransform;
_context.CurrentTransform = cont.LocalTransform;
}
}
}
@ -155,10 +187,20 @@ namespace Perspex.Media
PushedState PushSetTransform(Matrix matrix)
{
var oldMatrix = CurrentTransform;
_impl.Transform = matrix;
CurrentTransform = matrix;
return new PushedState(this, PushedState.PushedStateType.Matrix, oldMatrix);
}
public PushedState PushTransformContainer()
{
_transformContainers.Push(new TransformContainer(CurrentTransform, _currentContainerTransform));
_currentContainerTransform = CurrentTransform*_currentContainerTransform;
_currentTransform = Matrix.Identity;
return new PushedState(this, PushedState.PushedStateType.MatrixContainer);
}
public void Dispose() => _impl.Dispose();
}
}

4
src/Perspex.SceneGraph/Rendering/RendererBase.cs

@ -52,10 +52,10 @@ namespace Perspex.Rendering
}
m = renderTransform*m;
using (context.PushPreTransform(m))
using (context.PushPostTransform(m))
using (context.PushOpacity(opacity))
using (visual.ClipToBounds ? context.PushClip(new Rect(visual.Bounds.Size)) : default(DrawingContext.PushedState))
using (context.PushTransformContainer())
{
visual.Render(context);
foreach (var child in visual.VisualChildren.OrderBy(x => x.ZIndex))

Loading…
Cancel
Save