Skip to content

Commit

Permalink
Fixes #92 - Adds basic ReactTextViewManager without inline images
Browse files Browse the repository at this point in the history
Still remaining TODOs for text measurement and inline images.
  • Loading branch information
rozele committed Mar 1, 2016
1 parent 389e817 commit f8e5315
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 44 deletions.
2 changes: 2 additions & 0 deletions ReactWindows/ReactNative/ReactNative.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,11 @@
<Compile Include="UIManager\ViewManagersPropertyCache.cs" />
<Compile Include="UIManager\ViewProperties.cs" />
<Compile Include="Touch\ICatalystInterceptingViewGroup.cs" />
<Compile Include="Views\Text\InlineManager.cs" />
<Compile Include="Views\Text\ReactRawTextManager.cs" />
<Compile Include="Views\Text\ReactTextShadowNode.cs" />
<Compile Include="Views\Text\ReactTextViewManager.cs" />
<Compile Include="Views\Text\ReactVirtualTextViewManager.cs" />
<Compile Include="Views\View\ReactPanel.cs" />
<Compile Include="Views\View\ReactViewManager.cs" />
<EmbeddedResource Include="Properties\ReactNative.rd.xml" />
Expand Down
2 changes: 1 addition & 1 deletion ReactWindows/ReactNative/Shell/MainReactPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public IReadOnlyList<ViewManager> CreateViewManagers(
new ReactViewManager(),
//new ReactViewPagerManager(),
//new ReactTextInlineImageViewManager(),
//new ReactVirtualTextViewManager(),
new ReactVirtualTextViewManager(),
//new SwipeRefreshLayoutManager(),
//new ReactWebViewManager(),
};
Expand Down
2 changes: 1 addition & 1 deletion ReactWindows/ReactNative/UIManager/SizeMonitoringPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace ReactNative.UIManager
/// <summary>
/// allows registering for size change events. The main purpose for this class is to hide complexity of ReactRootView
/// </summary>
public partial class SizeMonitoringPanel : Grid
public partial class SizeMonitoringPanel : Canvas
{
private ISizeChangedListener _onSizeChangedListener;

Expand Down
35 changes: 35 additions & 0 deletions ReactWindows/ReactNative/Views/Text/InlineManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using Windows.UI.Xaml.Documents;

namespace ReactNative.Views.Text
{
abstract class InlineManager
{
private List<Action<Inline>> _actions = new List<Action<Inline>>();

public void Do(Action<Inline> 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;
}
}
}
174 changes: 139 additions & 35 deletions ReactWindows/ReactNative/Views/Text/ReactTextShadowNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
using ReactNative.UIManager;
using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using Windows.UI;
using Windows.UI.Text;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Documents;
using Windows.UI.Xaml.Media;

Expand All @@ -17,11 +17,6 @@ public class ReactTextShadowNode : LayoutShadowNode

private const string PROP_TEXT = "text";

private const string PROP_SHADOW_OFFSET = "textShadowOffset";
private const string PROP_SHADOW_RADIUS = "textShadowRadius";
private const string PROP_SHADOW_COLOR = "textShadowColor";
private const int DEFAULT_TEXT_SHADOW_COLOR = 0x55000000;

private int _lineHeight = UNSET;
private bool _isColorSet = false;
private int _color;
Expand All @@ -31,29 +26,19 @@ public class ReactTextShadowNode : LayoutShadowNode
private int _numberOfLines = UNSET;
private int _fontSize = UNSET;

private double _textShadowOffsetDx = 0.0;
private double _textShadowOffsetDy = 0.0;
private double _textShadowRadius = 1.0;
private int _textShadowColor = DEFAULT_TEXT_SHADOW_COLOR;

private FontStyle? _fontStyle;
private FontWeight? _fontWeight;

private string _fontFamily;
private string _text;

private string _inlineText;
private InlineManager _inline;

private readonly bool _isVirtual;

public ReactTextShadowNode(bool isVirtual)
{
_isVirtual = isVirtual;

if (!_isVirtual)
{
MeasureFunction = TextMeasureFunction;
}
}

public override bool IsVirtual
Expand All @@ -79,7 +64,7 @@ public override void OnBeforeLayout()
return;
}

_inlineText = FromTextCSSNode(this);
_inline = FromTextCSSNode(this);
MarkUpdated();
}

Expand All @@ -101,9 +86,9 @@ public override void OnCollectExtraUpdates(UIViewOperationQueue uiViewOperationQ
}

base.OnCollectExtraUpdates(uiViewOperationQueue);
if (_inlineText != null)
if (_inline != null)
{
uiViewOperationQueue.EnqueueUpdateExtraData(ReactTag, _inlineText);
uiViewOperationQueue.EnqueueUpdateExtraData(ReactTag, _inline);
}
}

Expand Down Expand Up @@ -135,6 +120,33 @@ public void SetFontSize(double fontSize)
MarkUpdated();
}

[ReactProperty(ViewProperties.Color)]
public void SetColor(int? color)
{
_isColorSet = color.HasValue;
if (_isColorSet)
{
_color = color.Value;
}

MarkUpdated();
}

[ReactProperty(ViewProperties.BackgroundColor)]
public void SetBackgroundColor(int? color)
{
if (!IsVirtualAnchor)
{
_isBackgroundColorSet = color.HasValue;
if (_isBackgroundColorSet)
{
_backgroundColor = color.Value;
}

MarkUpdated();
}
}

[ReactProperty(ViewProperties.FontFamily)]
public void SetFontFamily(string fontFamily)
{
Expand Down Expand Up @@ -188,12 +200,6 @@ public void SetFontStyle(string fontStyleString)
}
}

private static MeasureOutput TextMeasureFunction(CSSNode node, float width, float height)
{
// TODO: implement
return new MeasureOutput(width, height);
}

private static int ParseNumericFontWeight(string fontWeightString)
{
return fontWeightString.Length == 3 && fontWeightString.EndsWith("00") &&
Expand All @@ -202,20 +208,118 @@ private static int ParseNumericFontWeight(string fontWeightString)
: -1;
}

private static string FromTextCSSNode(ReactTextShadowNode textNode)
private static InlineManager FromTextCSSNode(ReactTextShadowNode textNode)
{
var builder = new StringBuilder();
for (var i = 0; i < textNode.ChildCount; ++i)
return BuildInlineFromTextCSSNode(textNode);
}

private static InlineManager BuildInlineFromTextCSSNode(ReactTextShadowNode textNode)
{
var length = textNode.ChildCount;
var inline = default(InlineManager);
if (length == 0)
{
inline = new RunManager(textNode._text);
}
else
{
var child = textNode.GetChildAt(i);
var textChild = child as ReactTextShadowNode;
if (textChild != null)
var span = new SpanManager();
for (var i = 0; i < length; ++i)
{
builder.Append(textChild._text);
var child = textNode.GetChildAt(i);
var textChild = child as ReactTextShadowNode;
if (textChild == null)
{
throw new InvalidOperationException(
string.Format(
CultureInfo.InvariantCulture,
"Unexpected view type '{0}' nested under text node.",
child.GetType()));
}

var childInline = BuildInlineFromTextCSSNode(textChild);
span.Add(childInline);
}

inline = span;
}

if (textNode._isColorSet)
{
var color = textNode._color;
var b = (byte)color;
color >>= 8;
var g = (byte)color;
color >>= 8;
var r = (byte)color;
color >>= 8;
var a = (byte)color;
var brush = new SolidColorBrush(Color.FromArgb(a, r, g, b));
inline.Do(i => i.Foreground = brush);
}

return builder.ToString();
if (textNode._fontSize != UNSET)
{
var fontSize = textNode._fontSize;
inline.Do(i => i.FontSize = fontSize);
}

if (textNode._fontStyle.HasValue)
{
var fontStyle = textNode._fontStyle.Value;
inline.Do(i => i.FontStyle = fontStyle);
}

if (textNode._fontWeight.HasValue)
{
var fontWeight = textNode._fontWeight.Value;
inline.Do(i => i.FontWeight = fontWeight);
}

if (textNode._fontFamily != null)
{
var fontFamily = new FontFamily(textNode._fontFamily);
inline.Do(i => i.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<InlineManager> _children = new List<InlineManager>();

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;
}
}
}
}
9 changes: 3 additions & 6 deletions ReactWindows/ReactNative/Views/Text/ReactTextViewManager.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
using System;
using ReactNative.UIManager;
using ReactNative.UIManager;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Text;

namespace ReactNative.Views.Text
{
Expand Down Expand Up @@ -30,8 +27,8 @@ protected override ReactTextShadowNode CreateShadowNodeInstanceCore()

protected override void UpdateExtraData(TextBlock root, object extraData)
{
var stringData = (string)extraData;
root.Text = stringData;
var inlineManager = (InlineManager)extraData;
root.Inlines.Add(inlineManager.Evaluate());
}
}
}
15 changes: 15 additions & 0 deletions ReactWindows/ReactNative/Views/Text/ReactVirtualTextViewManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace ReactNative.Views.Text
{
public class ReactVirtualTextViewManager : ReactRawTextManager
{
private const string ReactClass = "RCTVirtualText";

public override string Name
{
get
{
return ReactClass;
}
}
}
}
2 changes: 1 addition & 1 deletion ReactWindows/ReactNative/Views/View/ReactPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace ReactNative.Views.View
/// aren't common, lazy initializes most of the storage needed for them. Also supports
/// 3D transformations such as elevation depth.
/// </summary>
public class ReactPanel : Grid, ICatalystInterceptingViewGroup, ReactPointerEventsView
public class ReactPanel : Canvas, ICatalystInterceptingViewGroup, ReactPointerEventsView
{
private IOnInterceptTouchEventListener _onInterceptTouchEventListener;
private PointerEvents _PointerEvents = PointerEvents.Auto;
Expand Down

0 comments on commit f8e5315

Please sign in to comment.