From e893d3a4434fb00ffb7fcd7da09bf33cf595de49 Mon Sep 17 00:00:00 2001 From: Eric Rozell Date: Fri, 8 Jan 2016 13:48:37 -0500 Subject: [PATCH] Adds proper layout measurement for the ReactTextViewManager. In order to leverage the CSSNode class to its fullest, various view managers need to override the measurement algorithm to determine the proper width and height needed for a view. For now, we needed to move the measurement of FrameworkElements to the dispatcher thread, as WinRT does not have any text formatter or other hooks for determining the size of text without mimicking the element itself. Issue #106 covers this. --- .../Playground/Resources/main.dev.jsbundle | 4 +- ReactWindows/ReactNative/ReactNative.csproj | 8 +- .../ReactNative/Shell/MainReactPackage.cs | 3 +- .../UIManager/NativeViewHierarchyManager.cs | 29 ++++- .../UIManager/NativeViewHierarchyOptimizer.cs | 4 +- ...er.Generic.cs => PanelViewGroupManager.cs} | 104 +++++++++++++++++- .../ReactNative/UIManager/RootViewManager.cs | 8 +- .../ReactNative/UIManager/UIImplementation.cs | 4 +- .../ReactNative/UIManager/UIManagerModule.cs | 15 ++- .../UIManager/UIViewOperationQueue.cs | 19 ++-- .../ReactNative/UIManager/ViewGroupManager.cs | 28 +---- .../ReactNative/UIManager/ViewProperties.cs | 1 - .../Views/Scroll/ReactScrollViewManager.cs | 49 +++++++++ .../ReactNative/Views/Text/InlineManager.cs | 35 ------ .../Views/Text/ReactTextShadowNode.cs | 104 +++++++++--------- .../Views/Text/ReactTextViewManager.cs | 6 +- .../Views/TextInput/ReactTextInputManager.cs | 2 +- .../Views/View/ReactViewManager.cs | 14 +-- 18 files changed, 282 insertions(+), 155 deletions(-) rename ReactWindows/ReactNative/UIManager/{ViewGroupManager.Generic.cs => PanelViewGroupManager.cs} (66%) create mode 100644 ReactWindows/ReactNative/Views/Scroll/ReactScrollViewManager.cs delete mode 100644 ReactWindows/ReactNative/Views/Text/InlineManager.cs diff --git a/ReactWindows/Playground/Resources/main.dev.jsbundle b/ReactWindows/Playground/Resources/main.dev.jsbundle index 67546e62a1e..795c97cd58b 100644 --- a/ReactWindows/Playground/Resources/main.dev.jsbundle +++ b/ReactWindows/Playground/Resources/main.dev.jsbundle @@ -1194,7 +1194,9 @@ var ReactRoot=React.createClass({displayName:'ReactRoot', render:function(){ return ( React.createElement(View,{elevation:'1.0'}, -React.createElement(Text,null,'Hello React Native')));}}); +React.createElement(View,{style:{marginLeft:200}}, +React.createElement(View,{style:{marginTop:10}}, +React.createElement(Text,{style:{color:'red'}},"Hello React Native")))));}}); diff --git a/ReactWindows/ReactNative/ReactNative.csproj b/ReactWindows/ReactNative/ReactNative.csproj index 928cf6469a2..d1187f84482 100644 --- a/ReactWindows/ReactNative/ReactNative.csproj +++ b/ReactWindows/ReactNative/ReactNative.csproj @@ -244,13 +244,13 @@ - + + - @@ -262,8 +262,8 @@ - - + + diff --git a/ReactWindows/ReactNative/Shell/MainReactPackage.cs b/ReactWindows/ReactNative/Shell/MainReactPackage.cs index 120303e99d7..267b04fd0f3 100644 --- a/ReactWindows/ReactNative/Shell/MainReactPackage.cs +++ b/ReactWindows/ReactNative/Shell/MainReactPackage.cs @@ -2,6 +2,7 @@ using ReactNative.Modules.Core; using ReactNative.Modules.WebSocket; using ReactNative.UIManager; +using ReactNative.Views.Scroll; using ReactNative.Views.Text; using ReactNative.Views.TextInput; using ReactNative.Views.View; @@ -39,7 +40,7 @@ public IReadOnlyList CreateViewManagers( //new ReactProgressBarViewManager(), new ReactRawTextManager(), //new RecyclerViewBackedScrollViewManager(), - //new ReactScrollViewManager(), + new ReactScrollViewManager(), //new ReactSwitchManager(), new ReactTextInputManager(), new ReactTextViewManager(), diff --git a/ReactWindows/ReactNative/UIManager/NativeViewHierarchyManager.cs b/ReactWindows/ReactNative/UIManager/NativeViewHierarchyManager.cs index 5409535b0ab..e7d75264fe5 100644 --- a/ReactWindows/ReactNative/UIManager/NativeViewHierarchyManager.cs +++ b/ReactWindows/ReactNative/UIManager/NativeViewHierarchyManager.cs @@ -133,8 +133,23 @@ public void UpdateLayout(int parentTag, int tag, int x, int y, int width, int he .With("tag", tag)) { var viewToUpdate = ResolveView(tag); - // TODO: call viewToUpdate.Measure() - //throw new NotImplementedException(); + + var parentViewManager = default(ViewManager); + var parentViewGroupManager = default(ViewGroupManager); + if (!_tagsToViewManagers.TryGetValue(parentTag, out parentViewManager) || + (parentViewGroupManager = parentViewManager as ViewGroupManager) == null) + { + throw new InvalidOperationException( + string.Format( + CultureInfo.InvariantCulture, + "Trying to use view with tag '{0}' as a parent, but its manager doesn't extend ViewGroupManager.", + tag)); + } + + if (!parentViewGroupManager.NeedsCustomLayoutForChildren) + { + UpdateLayout(viewToUpdate, x, y, width, height); + } } } @@ -189,7 +204,7 @@ public void ManageChildren(int tag, int[] indicesToRemove, ViewAtIndex[] viewsTo } var viewGroupManager = (ViewGroupManager)viewManager; - var viewToManage = (Panel)_tagsToViews[tag]; + var viewToManage = _tagsToViews[tag]; var lastIndexToRemove = viewGroupManager.GetChildCount(viewToManage); if (indicesToRemove != null) @@ -513,5 +528,13 @@ private void DropView(FrameworkElement view) _tagsToViews.Remove(tag); _tagsToViewManagers.Remove(tag); } + + private void UpdateLayout(FrameworkElement viewToUpdate, int x, int y, int width, int height) + { + viewToUpdate.Width = width; + viewToUpdate.Height = height; + Canvas.SetLeft(viewToUpdate, x); + Canvas.SetTop(viewToUpdate, y); + } } } diff --git a/ReactWindows/ReactNative/UIManager/NativeViewHierarchyOptimizer.cs b/ReactWindows/ReactNative/UIManager/NativeViewHierarchyOptimizer.cs index 642db078d0f..61c5ad5b6b7 100644 --- a/ReactWindows/ReactNative/UIManager/NativeViewHierarchyOptimizer.cs +++ b/ReactWindows/ReactNative/UIManager/NativeViewHierarchyOptimizer.cs @@ -79,7 +79,7 @@ public void HandleCreateView( _uiViewOperationQueue.EnqueueCreateView( themedContext, node.ReactTag, - node.ViewClassName, + node.ViewClass, initialProperties); #else var isLayoutOnly = node.ViewClass == ViewProperties.ViewClassName @@ -376,7 +376,7 @@ private void ApplyLayoutRecursive(ReactShadowNode node, int x, int y) if (!node.IsLayoutOnly && node.NativeParent != null) { _uiViewOperationQueue.EnqueueUpdateLayout( - node.Parent.ReactTag, + node.NativeParent.ReactTag, node.ReactTag, x, y, diff --git a/ReactWindows/ReactNative/UIManager/ViewGroupManager.Generic.cs b/ReactWindows/ReactNative/UIManager/PanelViewGroupManager.cs similarity index 66% rename from ReactWindows/ReactNative/UIManager/ViewGroupManager.Generic.cs rename to ReactWindows/ReactNative/UIManager/PanelViewGroupManager.cs index b9016a51374..ab9abc5332c 100644 --- a/ReactWindows/ReactNative/UIManager/ViewGroupManager.Generic.cs +++ b/ReactWindows/ReactNative/UIManager/PanelViewGroupManager.cs @@ -9,7 +9,7 @@ namespace ReactNative.UIManager /// extending . /// /// Type of panel. - public abstract class ViewGroupManager : ViewGroupManager + public abstract class PanelViewGroupManager : ViewGroupManager where TPanel : Panel { /// @@ -53,6 +53,57 @@ public sealed override void UpdateExtraData(FrameworkElement root, object extraD UpdateExtraData((TPanel)root, extraData); } + /// + /// Gets the number of children in the view group. + /// + /// The view group. + /// The number of children. + public sealed override int GetChildCount(FrameworkElement parent) + { + return GetChildCount((TPanel)parent); + } + + /// + /// Gets the child at the given index. + /// + /// The parent view. + /// The index. + /// The child view. + public sealed override FrameworkElement GetChildAt(FrameworkElement parent, int index) + { + return GetChildAt((TPanel)parent, index); + } + + /// + /// Adds a child at the given index. + /// + /// The parent view. + /// The child view. + /// The index. + public sealed override void AddView(FrameworkElement parent, FrameworkElement child, int index) + { + AddView((TPanel)parent, child, index); + } + + /// + /// Removes the child at the given index. + /// + /// The view group. + /// The index. + public override void RemoveChildAt(FrameworkElement parent, int index) + { + RemoveChildAt((TPanel)parent, index); + } + + /// + /// Removes all children from the view group. + /// + /// The view group. + public override void RemoveAllChildren(FrameworkElement parent) + { + RemoveAllChildren((TPanel)parent); + } + /// /// Subclasses can override this method to install custom event /// emitters on the given view. @@ -172,5 +223,56 @@ protected virtual void ReceiveCommand(TPanel view, int commandId, JArray args) protected virtual void UpdateExtraData(TPanel root, object extraData) { } + + /// + /// Gets the number of children in the view group. + /// + /// The view group. + /// The number of children. + protected virtual int GetChildCount(TPanel parent) + { + return parent.Children.Count; + } + + /// + /// Gets the child at the given index. + /// + /// The parent view. + /// The index. + /// The child view. + protected virtual FrameworkElement GetChildAt(TPanel parent, int index) + { + return (FrameworkElement)parent.Children[index]; + } + + /// + /// Adds a child at the given index. + /// + /// The parent view. + /// The child view. + /// The index. + protected virtual void AddView(TPanel parent, FrameworkElement child, int index) + { + parent.Children.Insert(index, child); + } + + /// + /// Removes the child at the given index. + /// + /// The view group. + /// The index. + protected virtual void RemoveChildAt(TPanel parent, int index) + { + parent.Children.RemoveAt(index); + } + + /// + /// Removes all children from the view group. + /// + /// The view group. + protected virtual void RemoveAllChildren(TPanel parent) + { + parent.Children.Clear(); + } } } diff --git a/ReactWindows/ReactNative/UIManager/RootViewManager.cs b/ReactWindows/ReactNative/UIManager/RootViewManager.cs index f2aebefd5ad..c1b5c7c8f4d 100644 --- a/ReactWindows/ReactNative/UIManager/RootViewManager.cs +++ b/ReactWindows/ReactNative/UIManager/RootViewManager.cs @@ -1,11 +1,9 @@ -using Windows.UI.Xaml; - -namespace ReactNative.UIManager +namespace ReactNative.UIManager { /// /// View manager for react root view components. /// - public class RootViewManager : ViewGroupManager + public class RootViewManager : PanelViewGroupManager { /// /// The name of the react root view. @@ -23,7 +21,7 @@ public override string Name /// /// The react context. /// The view instance. - protected override FrameworkElement CreateViewInstance(ThemedReactContext reactContext) + protected override SizeMonitoringPanel CreateViewInstanceCore(ThemedReactContext reactContext) { return new SizeMonitoringPanel(); } diff --git a/ReactWindows/ReactNative/UIManager/UIImplementation.cs b/ReactWindows/ReactNative/UIManager/UIImplementation.cs index 507661dbb8f..8509811e0dc 100644 --- a/ReactWindows/ReactNative/UIManager/UIImplementation.cs +++ b/ReactWindows/ReactNative/UIManager/UIImplementation.cs @@ -463,6 +463,8 @@ public void MeasureLayoutRelativeToParent(int tag, ICallback errorCallback, ICal /// The batch identifier. public void DispatchViewUpdates(EventDispatcher eventDispatcher, int batchId) { + DispatcherHelpers.AssertOnDispatcher(); + foreach (var tag in _shadowNodeRegistry.RootNodeTags) { var cssRoot = _shadowNodeRegistry.GetNode(tag); @@ -472,7 +474,7 @@ public void DispatchViewUpdates(EventDispatcher eventDispatcher, int batchId) } _nativeViewHierarchyOptimizer.OnBatchComplete(); - _operationsQueue.DispatchViewUpdates(batchId); + _operationsQueue.ExecuteOperations(batchId); } /// diff --git a/ReactWindows/ReactNative/UIManager/UIManagerModule.cs b/ReactWindows/ReactNative/UIManager/UIManagerModule.cs index a91ee14ef29..7b8ef01689f 100644 --- a/ReactWindows/ReactNative/UIManager/UIManagerModule.cs +++ b/ReactWindows/ReactNative/UIManager/UIManagerModule.cs @@ -387,13 +387,16 @@ public void OnBatchComplete() { var batchId = _batchId++; - using (Tracer.Trace(Tracer.TRACE_TAG_REACT_BRIDGE, "onBatchCompleteUI") - .With("BatchId", batchId)) + Context.RunOnDispatcherQueueThread(() => { - _uiImplementation.DispatchViewUpdates(_eventDispatcher, batchId); - } - - // TODO: coordinate with UI operations? + using (Tracer.Trace(Tracer.TRACE_TAG_REACT_BRIDGE, "onBatchCompleteUI") + .With("BatchId", batchId)) + { + _uiImplementation.DispatchViewUpdates(_eventDispatcher, batchId); + } + }); + + // TODO: coordinate with UI operations a la choreographer? _eventDispatcher.OnBatchComplete(); } diff --git a/ReactWindows/ReactNative/UIManager/UIViewOperationQueue.cs b/ReactWindows/ReactNative/UIManager/UIViewOperationQueue.cs index 7a5f4c143ec..77ec05e3fb4 100644 --- a/ReactWindows/ReactNative/UIManager/UIViewOperationQueue.cs +++ b/ReactWindows/ReactNative/UIManager/UIViewOperationQueue.cs @@ -312,8 +312,10 @@ public void EnqueueFindTargetForTouch( /// Dispatches the view updates. /// /// The batch identifier. - internal void DispatchViewUpdates(int batchId) + internal void ExecuteOperations(int batchId) { + DispatcherHelpers.AssertOnDispatcher(); + var operations = default(IList); lock (_operationsLock) { @@ -324,20 +326,17 @@ internal void DispatchViewUpdates(int batchId) } } - _reactContext.RunOnDispatcherQueueThread(() => + using (Tracer.Trace(Tracer.TRACE_TAG_REACT_BRIDGE, "DispatchUI") + .With("BatchId", batchId)) { - using (Tracer.Trace(Tracer.TRACE_TAG_REACT_BRIDGE, "DispatchUI") - .With("BatchId", batchId)) + if (operations != null) { - if (operations != null) + foreach (var operation in operations) { - foreach (var operation in operations) - { - operation(); - } + operation(); } } - }); + } } private void EnqueueOperation(Action action) diff --git a/ReactWindows/ReactNative/UIManager/ViewGroupManager.cs b/ReactWindows/ReactNative/UIManager/ViewGroupManager.cs index ac6b202e4c1..97b8d97c155 100644 --- a/ReactWindows/ReactNative/UIManager/ViewGroupManager.cs +++ b/ReactWindows/ReactNative/UIManager/ViewGroupManager.cs @@ -5,8 +5,7 @@ namespace ReactNative.UIManager { /// - /// Class providing child management API for view managers of classes - /// extending . + /// Class providing child management API for view managers. /// public abstract class ViewGroupManager : ViewManager { @@ -57,20 +56,14 @@ public override void UpdateExtraData(FrameworkElement root, object extraData) /// The parent view. /// The child view. /// The index. - public virtual void AddView(Panel parent, UIElement child, int index) - { - parent.Children.Insert(index, child); - } + public abstract void AddView(FrameworkElement parent, FrameworkElement child, int index); /// /// Gets the number of children in the view group. /// /// The view group. /// The number of children. - public virtual int GetChildCount(Panel parent) - { - return parent.Children.Count; - } + public abstract int GetChildCount(FrameworkElement parent); /// /// Gets the child at the given index. @@ -78,28 +71,19 @@ public virtual int GetChildCount(Panel parent) /// The parent view. /// The index. /// The child view. - public virtual FrameworkElement GetChildAt(Panel parent, int index) - { - return (FrameworkElement)parent.Children[index]; - } + public abstract FrameworkElement GetChildAt(FrameworkElement parent, int index); /// /// Removes the child at the given index. /// /// The view group. /// The index. - public virtual void RemoveChildAt(Panel parent, int index) - { - parent.Children.RemoveAt(index); - } + public abstract void RemoveChildAt(FrameworkElement parent, int index); /// /// Removes all children from the view group. /// /// The view group. - public virtual void RemoveAllChildren(Panel parent) - { - parent.Children.Clear(); - } + public abstract void RemoveAllChildren(FrameworkElement parent); } } diff --git a/ReactWindows/ReactNative/UIManager/ViewProperties.cs b/ReactWindows/ReactNative/UIManager/ViewProperties.cs index 9d03398f3be..b17e08490ec 100644 --- a/ReactWindows/ReactNative/UIManager/ViewProperties.cs +++ b/ReactWindows/ReactNative/UIManager/ViewProperties.cs @@ -10,7 +10,6 @@ namespace ReactNative.UIManager public static class ViewProperties { public const string ViewClassName = "RCTView"; - public const string TextInputClassName = "RCTTextField"; // Layout only (only affect positions of children, causes no drawing) // !!! Keep in sync with s_layoutOnlyProperties below !!! diff --git a/ReactWindows/ReactNative/Views/Scroll/ReactScrollViewManager.cs b/ReactWindows/ReactNative/Views/Scroll/ReactScrollViewManager.cs new file mode 100644 index 00000000000..955a7b5a62c --- /dev/null +++ b/ReactWindows/ReactNative/Views/Scroll/ReactScrollViewManager.cs @@ -0,0 +1,49 @@ +using ReactNative.UIManager; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; + +namespace ReactNative.Views.Scroll +{ + public class ReactScrollViewManager : ViewGroupManager + { + private const string ReactClass = "RCTScrollView"; + + public override string Name + { + get + { + return ReactClass; + } + } + + public override void AddView(FrameworkElement parent, FrameworkElement child, int index) + { + ((ListView)parent).Items.Insert(index, child); + } + + public override FrameworkElement GetChildAt(FrameworkElement parent, int index) + { + return (FrameworkElement)((ListView)parent).Items[index]; + } + + public override int GetChildCount(FrameworkElement parent) + { + return ((ListView)parent).Items.Count; + } + + public override void RemoveAllChildren(FrameworkElement parent) + { + ((ListView)parent).Items.Clear(); + } + + public override void RemoveChildAt(FrameworkElement parent, int index) + { + ((ListView)parent).Items.RemoveAt(index); + } + + protected override FrameworkElement CreateViewInstance(ThemedReactContext reactContext) + { + return new ListView(); + } + } +} diff --git a/ReactWindows/ReactNative/Views/Text/InlineManager.cs b/ReactWindows/ReactNative/Views/Text/InlineManager.cs deleted file mode 100644 index e8227923411..00000000000 --- a/ReactWindows/ReactNative/Views/Text/InlineManager.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using Windows.UI.Xaml.Documents; - -namespace ReactNative.Views.Text -{ - abstract class InlineManager - { - private List> _actions = new List>(); - - public void Do(Action action) - { - _actions.Add(action); - } - - protected abstract Inline Create(); - - public Inline Evaluate() - { - var inline = Create(); - - foreach (var action in _actions) - { - action(inline); - } - - foreach (var action in _actions) - { - action(inline); - } - - return inline; - } - } -} diff --git a/ReactWindows/ReactNative/Views/Text/ReactTextShadowNode.cs b/ReactWindows/ReactNative/Views/Text/ReactTextShadowNode.cs index 5fba37e912c..be3ba4c7702 100644 --- a/ReactWindows/ReactNative/Views/Text/ReactTextShadowNode.cs +++ b/ReactWindows/ReactNative/Views/Text/ReactTextShadowNode.cs @@ -1,10 +1,13 @@ using Facebook.CSSLayout; +using ReactNative.Bridge; using ReactNative.UIManager; using System; using System.Collections.Generic; using System.Globalization; +using Windows.Foundation; using Windows.UI; using Windows.UI.Text; +using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Documents; using Windows.UI.Xaml.Media; @@ -32,13 +35,18 @@ public class ReactTextShadowNode : LayoutShadowNode private string _fontFamily; private string _text; - private InlineManager _inline; + private Inline _inline; private readonly bool _isVirtual; public ReactTextShadowNode(bool isVirtual) { _isVirtual = isVirtual; + + if (!isVirtual) + { + MeasureFunction = MeasureText; + } } public override bool IsVirtual @@ -59,6 +67,12 @@ public override bool IsVirtualAnchor public override void OnBeforeLayout() { + // We need to perform this operation on the dispatcher in UWP as + // WinRT lacks the tools needed to "predict" the height of text. + // Instead, we simply instantiate the Inline object, insert it into + // a text block, and extract how tall the element will be. + DispatcherHelpers.AssertOnDispatcher(); + if (_isVirtual) { return; @@ -200,6 +214,35 @@ public void SetFontStyle(string fontStyleString) } } + private static MeasureOutput MeasureText(CSSNode node, float width, float height) + { + // This is not a terribly efficient way of projecting the height of + // the text elements. It requires that we have access to the + // dispatcher in order to do measurement, which, for obvious + // reasons, can cause perceived performance issues as it will block + // the UI thread from handling other work. + // + // TODO: determine another way to measure text elements. + + var shadowNode = (ReactTextShadowNode)node; + var textBlock = new TextBlock(); + textBlock.Inlines.Add(shadowNode._inline); + + try + { + var adjustedWidth = float.IsNaN(width) ? double.PositiveInfinity : width; + var adjustedHeight = float.IsNaN(height) ? double.PositiveInfinity : height; + textBlock.Measure(new Size(width, adjustedHeight)); + return new MeasureOutput( + (float)textBlock.DesiredSize.Width, + (float)textBlock.DesiredSize.Height); + } + finally + { + textBlock.Inlines.Clear(); + } + } + private static int ParseNumericFontWeight(string fontWeightString) { return fontWeightString.Length == 3 && fontWeightString.EndsWith("00") && @@ -208,22 +251,22 @@ private static int ParseNumericFontWeight(string fontWeightString) : -1; } - private static InlineManager FromTextCSSNode(ReactTextShadowNode textNode) + private static Inline FromTextCSSNode(ReactTextShadowNode textNode) { return BuildInlineFromTextCSSNode(textNode); } - private static InlineManager BuildInlineFromTextCSSNode(ReactTextShadowNode textNode) + private static Inline BuildInlineFromTextCSSNode(ReactTextShadowNode textNode) { var length = textNode.ChildCount; - var inline = default(InlineManager); + var inline = default(Inline); if (length == 0) { - inline = new RunManager(textNode._text); + inline = new Run { Text = textNode._text }; } else { - var span = new SpanManager(); + var span = new Span(); for (var i = 0; i < length; ++i) { var child = textNode.GetChildAt(i); @@ -238,7 +281,7 @@ private static InlineManager BuildInlineFromTextCSSNode(ReactTextShadowNode text } var childInline = BuildInlineFromTextCSSNode(textChild); - span.Add(childInline); + span.Inlines.Add(childInline); } inline = span; @@ -255,71 +298,34 @@ private static InlineManager BuildInlineFromTextCSSNode(ReactTextShadowNode text color >>= 8; var a = (byte)color; var c = Color.FromArgb(a, r, g, b); - inline.Do(i => i.Foreground = new SolidColorBrush(c)); + inline.Foreground = new SolidColorBrush(c); } if (textNode._fontSize != UNSET) { var fontSize = textNode._fontSize; - inline.Do(i => i.FontSize = fontSize); + inline.FontSize = fontSize; } if (textNode._fontStyle.HasValue) { var fontStyle = textNode._fontStyle.Value; - inline.Do(i => i.FontStyle = fontStyle); + inline.FontStyle = fontStyle; } if (textNode._fontWeight.HasValue) { var fontWeight = textNode._fontWeight.Value; - inline.Do(i => i.FontWeight = fontWeight); + inline.FontWeight = fontWeight; } if (textNode._fontFamily != null) { var fontFamily = new FontFamily(textNode._fontFamily); - inline.Do(i => i.FontFamily = fontFamily); + inline.FontFamily = fontFamily; } return inline; } - - class RunManager : InlineManager - { - private readonly string _text; - - public RunManager(string text) - { - _text = text; - } - - protected override Inline Create() - { - return new Run { Text = _text }; - } - } - - class SpanManager : InlineManager - { - private readonly List _children = new List(); - - public void Add(InlineManager child) - { - _children.Add(child); - } - - protected override Inline Create() - { - var span = new Span(); - - foreach (var child in _children) - { - span.Inlines.Add(child.Evaluate()); - } - - return span; - } - } } } \ No newline at end of file diff --git a/ReactWindows/ReactNative/Views/Text/ReactTextViewManager.cs b/ReactWindows/ReactNative/Views/Text/ReactTextViewManager.cs index adcae94941f..40042a0f7a7 100644 --- a/ReactWindows/ReactNative/Views/Text/ReactTextViewManager.cs +++ b/ReactWindows/ReactNative/Views/Text/ReactTextViewManager.cs @@ -1,5 +1,6 @@ using ReactNative.UIManager; using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Documents; namespace ReactNative.Views.Text { @@ -27,8 +28,9 @@ protected override ReactTextShadowNode CreateShadowNodeInstanceCore() protected override void UpdateExtraData(TextBlock root, object extraData) { - var inlineManager = (InlineManager)extraData; - root.Inlines.Add(inlineManager.Evaluate()); + var inline = (Inline)extraData; + + root.Inlines.Add(inline); } } } diff --git a/ReactWindows/ReactNative/Views/TextInput/ReactTextInputManager.cs b/ReactWindows/ReactNative/Views/TextInput/ReactTextInputManager.cs index 57f2189b644..e656e9f2a04 100644 --- a/ReactWindows/ReactNative/Views/TextInput/ReactTextInputManager.cs +++ b/ReactWindows/ReactNative/Views/TextInput/ReactTextInputManager.cs @@ -20,7 +20,7 @@ class ReactTextInputManager : BaseViewManager { private static readonly int FOCUS_TEXT_INPUT = 1; private static readonly int BLUR_TEXT_INPUT = 2; - private static readonly string REACT_CLASS = ViewProperties.TextInputClassName; + private static readonly string REACT_CLASS = "RCTTextField"; private const string PROP_ROTATION_X = "rotationX"; private const string PROP_TEXT_ALIGN = "textAlign"; diff --git a/ReactWindows/ReactNative/Views/View/ReactViewManager.cs b/ReactWindows/ReactNative/Views/View/ReactViewManager.cs index 20224e27dcd..c6a2d69e912 100644 --- a/ReactWindows/ReactNative/Views/View/ReactViewManager.cs +++ b/ReactWindows/ReactNative/Views/View/ReactViewManager.cs @@ -1,11 +1,7 @@ -using Facebook.CSSLayout; -using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Linq; using ReactNative.UIManager; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Windows.UI.Xaml; using Windows.UI.Xaml.Automation.Peers; using Windows.UI.Xaml.Automation.Provider; @@ -13,7 +9,7 @@ namespace ReactNative.Views.View { - public class ReactViewManager : ViewGroupManager + public class ReactViewManager : PanelViewGroupManager { public static readonly string REACT_CLASS = ViewProperties.ViewClassName; private static readonly int CMD_SET_PRESSED = 1; @@ -139,13 +135,9 @@ protected override void ReceiveCommand(ReactPanel view, int commandId, JArray ar /// The parent view. /// The child view. /// The index. - public override void AddView(Panel parent, UIElement child, int index) + protected override void AddView(ReactPanel parent, FrameworkElement child, int index) { parent.Children.Insert(index, child); } - - protected override void UpdateExtraData(ReactPanel root, object extraData) - { - } } }