Skip to content

Commit ba05035

Browse files
committed
fix(BaseViewManager): Remove dependency on WinRTXamlToolkit (microsoft#1218)
The `SetClipToBounds` property from `WinRTXamlToolkit` is too simple to implement to justify the dependency. Also, the approach that uses dimensions seems to be a bit less complex that relying on both a XAML dependency property and the SizeChanged event. Fixes microsoft#1214
1 parent aceb0f1 commit ba05035

File tree

2 files changed

+109
-15
lines changed

2 files changed

+109
-15
lines changed

ReactWindows/ReactNative/UIManager/BaseViewManager.cs

Lines changed: 109 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using ReactNative.UIManager.Annotations;
44
using System;
55
using System.Collections.Generic;
6+
using Windows.Foundation;
67
using Windows.UI.Xaml;
78
using Windows.UI.Xaml.Automation;
89
using Windows.UI.Xaml.Automation.Peers;
@@ -24,8 +25,8 @@ public abstract class BaseViewManager<TFrameworkElement, TLayoutShadowNode> :
2425
where TFrameworkElement : FrameworkElement
2526
where TLayoutShadowNode : LayoutShadowNode
2627
{
27-
private readonly IDictionary<TFrameworkElement, Action<TFrameworkElement, Dimensions>> _transforms =
28-
new Dictionary<TFrameworkElement, Action<TFrameworkElement, Dimensions>>();
28+
private readonly IDictionary<TFrameworkElement, DimensionBoundProperties> _dimensionBoundProperties =
29+
new Dictionary<TFrameworkElement, DimensionBoundProperties>();
2930

3031
/// <summary>
3132
/// Set's the <typeparamref name="TFrameworkElement"/> styling layout
@@ -36,14 +37,20 @@ public abstract class BaseViewManager<TFrameworkElement, TLayoutShadowNode> :
3637
[ReactProp("transform")]
3738
public void SetTransform(TFrameworkElement view, JArray transforms)
3839
{
39-
if (transforms == null && _transforms.Remove(view))
40+
if (transforms == null)
4041
{
41-
ResetProjectionMatrix(view);
42-
ResetRenderTransform(view);
42+
var dimensionBoundProperties = GetDimensionBoundProperties(view);
43+
if (dimensionBoundProperties?.MatrixTransform != null)
44+
{
45+
dimensionBoundProperties.MatrixTransform = null;
46+
ResetProjectionMatrix(view);
47+
ResetRenderTransform(view);
48+
}
4349
}
4450
else
4551
{
46-
_transforms[view] = (v, d) => SetProjectionMatrix(v, d, transforms);
52+
var dimensionBoundProperties = GetOrCreateDimensionBoundProperties(view);
53+
dimensionBoundProperties.MatrixTransform = transforms;
4754
var dimensions = GetDimensions(view);
4855
SetProjectionMatrix(view, dimensions, transforms);
4956
}
@@ -70,11 +77,19 @@ public void SetOverflow(TFrameworkElement view, string overflow)
7077
{
7178
if (overflow == "hidden")
7279
{
73-
WinRTXamlToolkit.Controls.Extensions.FrameworkElementExtensions.SetClipToBounds(view, true);
80+
var dimensionBoundProperties = GetOrCreateDimensionBoundProperties(view);
81+
dimensionBoundProperties.OverflowHidden = true;
82+
var dimensions = GetDimensions(view);
83+
SetOverflowHidden(view, dimensions);
7484
}
7585
else
7686
{
77-
WinRTXamlToolkit.Controls.Extensions.FrameworkElementExtensions.SetClipToBounds(view, false);
87+
var dimensionBoundProperties = GetDimensionBoundProperties(view);
88+
if (dimensionBoundProperties != null && dimensionBoundProperties.OverflowHidden)
89+
{
90+
dimensionBoundProperties.OverflowHidden = false;
91+
SetOverflowVisible(view);
92+
}
7893
}
7994
}
8095

@@ -147,7 +162,7 @@ public override void OnDropViewInstance(ThemedReactContext reactContext, TFramew
147162
{
148163
view.PointerEntered -= OnPointerEntered;
149164
view.PointerExited -= OnPointerExited;
150-
_transforms.Remove(view);
165+
_dimensionBoundProperties.Remove(view);
151166
}
152167

153168
/// <summary>
@@ -157,10 +172,17 @@ public override void OnDropViewInstance(ThemedReactContext reactContext, TFramew
157172
/// <param name="dimensions">The dimensions.</param>
158173
public override void SetDimensions(TFrameworkElement view, Dimensions dimensions)
159174
{
160-
Action<TFrameworkElement, Dimensions> applyTransform;
161-
if (_transforms.TryGetValue(view, out applyTransform))
175+
var dimensionBoundProperties = GetDimensionBoundProperties(view);
176+
var matrixTransform = dimensionBoundProperties?.MatrixTransform;
177+
var overflowHidden = dimensionBoundProperties?.OverflowHidden ?? false;
178+
if (matrixTransform != null)
179+
{
180+
SetProjectionMatrix(view, dimensions, matrixTransform);
181+
}
182+
183+
if (overflowHidden)
162184
{
163-
applyTransform(view, dimensions);
185+
SetOverflowHidden(view, dimensions);
164186
}
165187

166188
base.SetDimensions(view, dimensions);
@@ -197,6 +219,29 @@ private void OnPointerExited(object sender, PointerRoutedEventArgs e)
197219
TouchHandler.OnPointerExited(view, e);
198220
}
199221

222+
private DimensionBoundProperties GetDimensionBoundProperties(TFrameworkElement view)
223+
{
224+
DimensionBoundProperties properties;
225+
if (!_dimensionBoundProperties.TryGetValue(view, out properties))
226+
{
227+
properties = null;
228+
}
229+
230+
return properties;
231+
}
232+
233+
private DimensionBoundProperties GetOrCreateDimensionBoundProperties(TFrameworkElement view)
234+
{
235+
DimensionBoundProperties properties;
236+
if (!_dimensionBoundProperties.TryGetValue(view, out properties))
237+
{
238+
properties = new DimensionBoundProperties();
239+
_dimensionBoundProperties.Add(view, properties);
240+
}
241+
242+
return properties;
243+
}
244+
200245
private static void SetProjectionMatrix(TFrameworkElement view, Dimensions dimensions, JArray transforms)
201246
{
202247
var transformMatrix = TransformHelper.ProcessTransform(transforms);
@@ -224,12 +269,11 @@ private static void ApplyProjection(TFrameworkElement view, Matrix3D projectionM
224269
if (IsSimpleTranslationOnly(projectionMatrix))
225270
{
226271
ResetProjectionMatrix(view);
227-
var transform = new MatrixTransform();
272+
var transform = EnsureMatrixTransform(view);
228273
var matrix = transform.Matrix;
229274
matrix.OffsetX = projectionMatrix.OffsetX;
230275
matrix.OffsetY = projectionMatrix.OffsetY;
231276
transform.Matrix = matrix;
232-
view.RenderTransform = transform;
233277
}
234278
else
235279
{
@@ -271,6 +315,24 @@ private static void ResetRenderTransform(TFrameworkElement view)
271315
view.RenderTransform = null;
272316
}
273317

318+
private static MatrixTransform EnsureMatrixTransform(FrameworkElement view)
319+
{
320+
var transform = view.RenderTransform;
321+
var matrixTransform = transform as MatrixTransform;
322+
if (transform != null && matrixTransform == null)
323+
{
324+
throw new InvalidOperationException("Unknown transform set on framework element.");
325+
}
326+
327+
if (matrixTransform == null)
328+
{
329+
matrixTransform = new MatrixTransform();
330+
view.RenderTransform = matrixTransform;
331+
}
332+
333+
return matrixTransform;
334+
}
335+
274336
private static Matrix3DProjection EnsureProjection(FrameworkElement view)
275337
{
276338
var projection = view.Projection;
@@ -288,5 +350,38 @@ private static Matrix3DProjection EnsureProjection(FrameworkElement view)
288350

289351
return matrixProjection;
290352
}
353+
354+
private static void SetOverflowHidden(TFrameworkElement element, Dimensions dimensions)
355+
{
356+
if (double.IsNaN(dimensions.Width) || double.IsNaN(dimensions.Height))
357+
{
358+
element.Clip = null;
359+
}
360+
else
361+
{
362+
element.Clip = new RectangleGeometry
363+
{
364+
Rect = new Rect
365+
{
366+
X = 0,
367+
Y = 0,
368+
Width = dimensions.Width,
369+
Height = dimensions.Height,
370+
},
371+
};
372+
}
373+
}
374+
375+
private static void SetOverflowVisible(TFrameworkElement element)
376+
{
377+
element.Clip = null;
378+
}
379+
380+
class DimensionBoundProperties
381+
{
382+
public bool OverflowHidden { get; set; }
383+
384+
public JArray MatrixTransform { get; set; }
385+
}
291386
}
292387
}

ReactWindows/ReactNative/project.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
"OpenCover": "4.6.519",
88
"PCLStorage": "1.0.2",
99
"System.Reactive": "3.1.1",
10-
"WinRTXamlToolkit": "2.2.0"
1110
},
1211
"frameworks": {
1312
"uap10.0": {}

0 commit comments

Comments
 (0)