private static YogaSize MeasureText(ReactTextShadowNode textNode, YogaNode node, float width, YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode)
        {
            // TODO: Measure text with DirectWrite or other API that does not
            // require dispatcher access. Currently, we're instantiating a
            // second CoreApplicationView (that is never activated) and using
            // its Dispatcher thread to calculate layout.
            var textBlock = new TextBlock
            {
                TextAlignment = TextAlignment.Left,
                TextWrapping  = TextWrapping.Wrap,
                TextTrimming  = TextTrimming.CharacterEllipsis,
            };

            textNode.UpdateTextBlockCore(textBlock, true);

            for (var i = 0; i < textNode.ChildCount; ++i)
            {
                var child = textNode.GetChildAt(i);
                textBlock.Inlines.Add(ReactInlineShadowNodeVisitor.Apply(child));
            }

            var normalizedWidth  = YogaConstants.IsUndefined(width) ? double.PositiveInfinity : width;
            var normalizedHeight = YogaConstants.IsUndefined(height) ? double.PositiveInfinity : height;

            textBlock.Measure(new Size(normalizedWidth, normalizedHeight));
            return(MeasureOutput.Make(
                       (float)Math.Ceiling(textBlock.DesiredSize.Width),
                       (float)Math.Ceiling(textBlock.DesiredSize.Height)));
        }
        private static YogaSize MeasureTextInput(ReactTextInputShadowNode textInputNode, YogaNode node, float width, YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode)
        {
            textInputNode._computedPadding = textInputNode.GetComputedPadding();

            var normalizedWidth = Math.Max(0,
                                           (YogaConstants.IsUndefined(width) ? double.PositiveInfinity : width));

            var normalizedHeight = Math.Max(0,
                                            (YogaConstants.IsUndefined(height) ? double.PositiveInfinity : height));

            var normalizedText = string.IsNullOrEmpty(textInputNode._text) ? " " : textInputNode._text;

            var textBlock = new TextBlock
            {
                Text         = normalizedText,
                TextWrapping = textInputNode._multiline ? TextWrapping.Wrap : TextWrapping.NoWrap,
            };

            ApplyStyles(textInputNode, textBlock);

            textBlock.Measure(new Size(normalizedWidth, normalizedHeight));

            return(MeasureOutput.Make(
                       (float)Math.Ceiling(width),
                       (float)Math.Ceiling(textBlock.ActualHeight)));
        }
        private static YogaSize MeasurePasswordBox(ReactPasswordBoxShadowNode textInputNode, YogaNode node, float width, YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode)
        {
            var normalizedWidth = Math.Max(0,
                                           (YogaConstants.IsUndefined(width) ? double.PositiveInfinity : width));

            var normalizedHeight = Math.Max(0,
                                            (YogaConstants.IsUndefined(height) ? double.PositiveInfinity : height));

            var passwordChar   = GetDefaultPasswordChar();
            var normalizedText = !string.IsNullOrEmpty(textInputNode._text)
                ? new string(passwordChar[0], textInputNode._text.Length)
                : passwordChar;

            var textBlock = new TextBlock
            {
                Text = normalizedText,
            };

            ApplyStyles(textInputNode, textBlock);

            textBlock.Measure(new Size(normalizedWidth, normalizedHeight));

            return(MeasureOutput.Make(
                       (float)Math.Ceiling(width),
                       (float)Math.Ceiling(textBlock.ActualHeight)));
        }
Exemple #4
0
        /// <summary>
        /// Measures the width and height of a <see cref="ProgressRing"/>.
        /// </summary>
        /// <param name="node">The css style of the rendered <see cref="ProgressRing"/>.</param>
        /// <param name="width">The parameterized native width of the control.</param>
        /// <param name="widthMode">The width measurement mode.</param>
        /// <param name="height">The parameterized native height of the control.</param>
        /// <param name="heightMode">The height measurement mode.</param>
        /// <returns>The measurement <see cref="MeasureOutput"/> for the <see cref="ProgressRing"/> component.</returns>
        private static YogaSize MeasureProgressRing(YogaNode node, float width, YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode)
        {
            var normalizedWidth  = !YogaConstants.IsUndefined(width) ? width : 20f;
            var normalizedHeight = !YogaConstants.IsUndefined(height) ? height : 20f;

            return(MeasureOutput.Make(normalizedWidth, normalizedHeight));
        }
Exemple #5
0
        public static float GetPaddingValue(this ReactShadowNode node, int spacingType)
        {
            var padding = node.GetPadding(spacingType);

            if (!YogaConstants.IsUndefined(padding))
            {
                return(padding);
            }

            if (spacingType == EdgeSpacing.Left || spacingType == EdgeSpacing.Right)
            {
                padding = node.GetPadding(EdgeSpacing.Horizontal);
            }

            if (!YogaConstants.IsUndefined(padding))
            {
                return(padding);
            }

            if (spacingType == EdgeSpacing.Top || spacingType == EdgeSpacing.Bottom)
            {
                padding = node.GetPadding(EdgeSpacing.Vertical);
            }

            if (!YogaConstants.IsUndefined(padding))
            {
                return(padding);
            }

            return(node.GetPadding(EdgeSpacing.All));
        }
Exemple #6
0
        /// <summary>
        /// Set a spacing value.
        /// </summary>
        /// <param name="spacingType">
        /// One of <see cref="Left" />, <see cref="Top" />, <see cref="Right" />, <see cref="Bottom" />,
        /// <see cref="Vertical" />, <see cref="Horizontal" />, <see cref="All" />.
        /// </param>
        /// <param name="value">the value for this direction.</param>
        /// <returns>
        /// <code>true</code> if the spacing has changed, or <code>false</code>
        /// if the same value was already set.
        /// </returns>
        public bool Set(int spacingType, YogaValue value)
        {
            if (!EpsilonEqualityComparer.Instance.Equals(_spacing[spacingType], value))
            {
                _spacing[spacingType] = value;

                if (YogaConstants.IsUndefined(value))
                {
                    _valueFlags &= ~s_flagsMap[spacingType];
                }
                else
                {
                    _valueFlags |= s_flagsMap[spacingType];
                }

                _hasAliasesSet =
                    (_valueFlags & s_flagsMap[All]) != 0 ||
                    (_valueFlags & s_flagsMap[Vertical]) != 0 ||
                    (_valueFlags & s_flagsMap[Horizontal]) != 0;

                return(true);
            }

            return(false);
        }
        public static float GetLeftBorderWidth(this ReactShadowNode node)
        {
            var width = node.GetBorder(EdgeSpacing.Left);

            if (!YogaConstants.IsUndefined(width))
            {
                return(width);
            }

            if (!I18NUtil.IsRightToLeft)
            {
                width = node.GetBorder(YogaEdge.Start);
                if (!YogaConstants.IsUndefined(width))
                {
                    return(width);
                }
            }
            else
            {
                width = node.GetBorder(YogaEdge.End);
                if (!YogaConstants.IsUndefined(width))
                {
                    return(width);
                }
            }

            width = node.GetBorder(YogaEdge.All);
            if (!YogaConstants.IsUndefined(width))
            {
                return(width);
            }

            return(0.0f);
        }
Exemple #8
0
        private static YogaSize MeasureCanvas(YogaNode node, float width, YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode)
        {
            var adjustedHeight = YogaConstants.IsUndefined(height) ? 4f : height;
            var adjustedWidth  = YogaConstants.IsUndefined(width) ? 4f : width;

            return(MeasureOutput.Make(adjustedWidth, adjustedHeight));
        }
Exemple #9
0
        public static float GetPaddingSpace(this ReactShadowNode node, int spacingType)
        {
            var padding = node.GetPaddingValue(spacingType);

            return(YogaConstants.IsUndefined(padding)
                ? 0.0f
                : padding);
        }
        private static YogaSize MeasureTextInput(ReactTextInputShadowNode textInputNode, YogaNode node, float width, YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode)
        {
            textInputNode._computedPadding = textInputNode.GetComputedPadding();

            var borderLeftWidth  = textInputNode.GetBorder(YogaEdge.Left);
            var borderRightWidth = textInputNode.GetBorder(YogaEdge.Right);

            var normalizedWidth = Math.Max(0,
                                           (YogaConstants.IsUndefined(width) ? double.PositiveInfinity : width)
                                           - textInputNode._computedPadding[0]
                                           - textInputNode._computedPadding[2]
                                           - (YogaConstants.IsUndefined(borderLeftWidth) ? 0 : borderLeftWidth)
                                           - (YogaConstants.IsUndefined(borderRightWidth) ? 0 : borderRightWidth));
            var normalizedHeight = Math.Max(0, YogaConstants.IsUndefined(height) ? double.PositiveInfinity : 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 task = DispatcherHelpers.CallOnDispatcher(() =>
            {
                /*
                 * var textBlock = new TextBlock
                 * {
                 *  TextWrapping = TextWrapping.Wrap,
                 * };
                 *
                 * var normalizedText = string.IsNullOrEmpty(textNode._text) ? " " : textNode._text;
                 * var inline = new Run { Text = normalizedText };
                 * FormatInline(textNode, inline);
                 *
                 * textBlock.Inlines.Add(inline);
                 *
                 * textBlock.Measure(new Size(normalizedWidth, normalizedHeight));
                 *
                 * var borderTopWidth = textInputNode.GetBorder(CSSSpacingType.Top);
                 * var borderBottomWidth = textInputNode.GetBorder(CSSSpacingType.Bottom);
                 *
                 * var finalizedHeight = (float)textBlock.DesiredSize.Height;
                 * finalizedHeight += textInputNode._computedPadding[1];
                 * finalizedHeight += textInputNode._computedPadding[3];
                 * finalizedHeight += CSSConstants.IsUndefined(borderTopWidth) ? 0 : borderTopWidth;
                 * finalizedHeight += CSSConstants.IsUndefined(borderBottomWidth) ? 0 : borderBottomWidth;
                 *
                 * return new MeasureOutput(width, finalizedHeight);
                 */

                float finalizedHeight = 1;
                return(MeasureOutput.Make(
                           (float)Math.Ceiling(width),
                           (float)Math.Ceiling(finalizedHeight)));
            });

            return(task.Result);
        }
Exemple #11
0
        public void TestCopyStyle()
        {
            YogaNode node0 = new YogaNode();

            Assert.IsTrue(YogaConstants.IsUndefined(node0.MaxHeight));

            YogaNode node1 = new YogaNode();

            node1.MaxHeight = 100;

            node0.CopyStyle(node1);
            Assert.AreEqual(100, node0.MaxHeight);
        }
Exemple #12
0
        private static YogaSize MeasureTextInput(ReactPasswordBoxShadowNode textInputNode, YogaNode node, float width, YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode)
        {
            textInputNode._computedPadding = textInputNode.GetComputedPadding();

            var borderLeftWidth  = textInputNode.GetBorder(YogaEdge.Left);
            var borderRightWidth = textInputNode.GetBorder(YogaEdge.Right);

            var normalizedWidth = Math.Max(0,
                                           (YogaConstants.IsUndefined(width) ? double.PositiveInfinity : width)
                                           - textInputNode._computedPadding[0]
                                           - textInputNode._computedPadding[2]
                                           - (YogaConstants.IsUndefined(borderLeftWidth) ? 0 : borderLeftWidth)
                                           - (YogaConstants.IsUndefined(borderRightWidth) ? 0 : borderRightWidth));
            var normalizedHeight = Math.Max(0, YogaConstants.IsUndefined(height) ? double.PositiveInfinity : height);

            // TODO: Measure text with DirectWrite or other API that does not
            // require dispatcher access. Currently, we're instantiating a
            // second CoreApplicationView (that is never activated) and using
            // its Dispatcher thread to calculate layout.
            var textBlock = new TextBlock
            {
                TextWrapping = TextWrapping.Wrap,
            };

            var passwordChar   = GetDefaultPasswordChar();
            var normalizedText = !string.IsNullOrEmpty(textInputNode._text)
                ? new string(passwordChar[0], textInputNode._text.Length)
                : passwordChar;
            var inline = new Run {
                Text = normalizedText
            };

            FormatTextElement(textInputNode, inline);
            textBlock.Inlines.Add(inline);

            textBlock.Measure(new Size(normalizedWidth, normalizedHeight));

            var borderTopWidth    = textInputNode.GetBorder(YogaEdge.Top);
            var borderBottomWidth = textInputNode.GetBorder(YogaEdge.Bottom);

            var finalizedHeight = (float)textBlock.DesiredSize.Height;

            finalizedHeight += textInputNode._computedPadding[1];
            finalizedHeight += textInputNode._computedPadding[3];
            finalizedHeight += YogaConstants.IsUndefined(borderTopWidth) ? 0 : borderTopWidth;
            finalizedHeight += YogaConstants.IsUndefined(borderBottomWidth) ? 0 : borderBottomWidth;

            return(MeasureOutput.Make(
                       (float)Math.Ceiling(width),
                       (float)Math.Ceiling(finalizedHeight)));
        }
 private void UpdatePadding()
 {
     for (var spacingType = EdgeSpacing.Left; spacingType <= EdgeSpacing.All; spacingType++)
     {
         if (spacingType == EdgeSpacing.Left ||
             spacingType == EdgeSpacing.Right ||
             spacingType == EdgeSpacing.Start ||
             spacingType == EdgeSpacing.End)
         {
             if (YogaConstants.IsUndefined(_padding.GetRaw(spacingType)) &&
                 YogaConstants.IsUndefined(_padding.GetRaw(EdgeSpacing.Horizontal)) &&
                 YogaConstants.IsUndefined(_padding.GetRaw(EdgeSpacing.All)))
             {
                 SetPadding(_yogaNode, spacingType, _defaultPadding.GetRaw(spacingType));
             }
             else
             {
                 SetPadding(_yogaNode, spacingType, _padding.GetRaw(spacingType));
             }
         }
         else if (spacingType == EdgeSpacing.Top || spacingType == EdgeSpacing.Bottom)
         {
             if (YogaConstants.IsUndefined(_padding.GetRaw(spacingType)) &&
                 YogaConstants.IsUndefined(_padding.GetRaw(EdgeSpacing.Vertical)) &&
                 YogaConstants.IsUndefined(_padding.GetRaw(EdgeSpacing.All)))
             {
                 SetPadding(_yogaNode, spacingType, _defaultPadding.GetRaw(spacingType));
             }
             else
             {
                 SetPadding(_yogaNode, spacingType, _padding.GetRaw(spacingType));
             }
         }
         else
         {
             if (YogaConstants.IsUndefined(_padding.GetRaw(spacingType)))
             {
                 SetPadding(_yogaNode, spacingType, _defaultPadding.GetRaw(spacingType));
             }
             else
             {
                 SetPadding(_yogaNode, spacingType, _padding.GetRaw(spacingType));
             }
         }
     }
 }
        public static float GetTopBorderWidth(this ReactShadowNode node)
        {
            var width = node.GetBorder(YogaEdge.Top);

            if (!YogaConstants.IsUndefined(width))
            {
                return(width);
            }

            width = node.GetBorder(YogaEdge.All);
            if (!YogaConstants.IsUndefined(width))
            {
                return(width);
            }

            return(0.0f);
        }
        private static YogaSize MeasureTextInput(ReactTextInputShadowNode textInputNode, YogaNode node, float width, YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode)
        {
            textInputNode._computedPadding = textInputNode.GetComputedPadding();

            var borderLeftWidth  = textInputNode.GetBorder(YogaEdge.Left);
            var borderRightWidth = textInputNode.GetBorder(YogaEdge.Right);

            var normalizedWidth = Math.Max(0,
                                           (YogaConstants.IsUndefined(width) ? double.PositiveInfinity : width)
                                           - textInputNode._computedPadding[0]
                                           - textInputNode._computedPadding[2]
                                           - (YogaConstants.IsUndefined(borderLeftWidth) ? 0 : borderLeftWidth)
                                           - (YogaConstants.IsUndefined(borderRightWidth) ? 0 : borderRightWidth));
            var normalizedHeight = Math.Max(0, YogaConstants.IsUndefined(height) ? double.PositiveInfinity : height);

            var textBlock = new TextBlock
            {
                TextWrapping = TextWrapping.Wrap,
            };

            var normalizedText = string.IsNullOrEmpty(textInputNode._text) ? " " : textInputNode._text;
            var inline         = new Run {
                Text = normalizedText
            };

            FormatInline(textInputNode, inline);

            textBlock.Inlines.Add(inline);

            textBlock.Measure(new Size(normalizedWidth, normalizedHeight));

            var borderTopWidth    = textInputNode.GetBorder(YogaEdge.Top);
            var borderBottomWidth = textInputNode.GetBorder(YogaEdge.Bottom);

            var finalizedHeight = (float)textBlock.DesiredSize.Height;

            finalizedHeight += textInputNode._computedPadding[1];
            finalizedHeight += textInputNode._computedPadding[3];
            finalizedHeight += YogaConstants.IsUndefined(borderTopWidth) ? 0 : borderTopWidth;
            finalizedHeight += YogaConstants.IsUndefined(borderBottomWidth) ? 0 : borderBottomWidth;

            return(MeasureOutput.Make(
                       (float)Math.Ceiling(width),
                       (float)Math.Ceiling(finalizedHeight)));
        }
Exemple #16
0
        private static YogaSize MeasureText(ReactTextShadowNode textNode, YogaNode node, float width,
                                            YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode)
        {
            Log.Info(ReactConstants.Tag, "MeasureText node=" + textNode.ReactTag);
            // 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 task = DispatcherHelpers.CallOnDispatcher(() =>
            {
                if (textView == null)
                {
                    textView = new ReactTextView(ReactProgram.RctWindow);
                    textView.LineWrapType = WrapType.Mixed;
                }

                var normalizedWidth  = YogaConstants.IsUndefined(width) ? ReactProgram.RctWindow.ScreenSize.Width : width;
                var normalizedHeight = YogaConstants.IsUndefined(height) ? ReactProgram.RctWindow.ScreenSize.Height : height;
                textView.Resize((int)normalizedWidth, (int)normalizedHeight);

                textView.Text      = textNode._preparedSpannableText;
                var textPartObject = textView.EdjeObject["elm.text"];
                if (textPartObject == null)
                {
                    throw new Exception("Invalid ReactTextView.EdjeObject[\"elm.text\"]");
                }
                Size size = textPartObject.TextBlockFormattedSize;
                Log.Info(ReactConstants.Tag, "MeasureText result : width: " + size.Width + " height:" + size.Height);

                //textView.Unrealize();

                return(MeasureOutput.Make(
                           (float)size.Width,
                           (float)size.Height));
            });

            return(task.Result);
        }
Exemple #17
0
        private static YogaSize MeasureText(ReactTextShadowNode textNode, YogaNode node, float width, YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode)
        {
            // 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 task = DispatcherHelpers.CallOnDispatcher(() =>
            {
                var textBlock = new RichTextBlock
                {
                    TextWrapping  = TextWrapping.Wrap,
                    TextAlignment = TextAlignment.DetectFromContent,
                    TextTrimming  = TextTrimming.CharacterEllipsis,
                };

                textNode.UpdateTextBlockCore(textBlock, true);

                var block = new Paragraph();
                for (var i = 0; i < textNode.ChildCount; ++i)
                {
                    var child = textNode.GetChildAt(i);
                    block.Inlines.Add(ReactInlineShadowNodeVisitor.Apply(child));
                }
                textBlock.Blocks.Add(block);

                var normalizedWidth  = YogaConstants.IsUndefined(width) ? double.PositiveInfinity : width;
                var normalizedHeight = YogaConstants.IsUndefined(height) ? double.PositiveInfinity : height;
                textBlock.Measure(new Size(normalizedWidth, normalizedHeight));
                return(MeasureOutput.Make(
                           (float)Math.Ceiling(textBlock.DesiredSize.Width),
                           (float)Math.Ceiling(textBlock.DesiredSize.Height)));
            });

            return(task.Result);
        }
        private YogaSize MeasureButton(ReactButtonShadowNode textNode, YogaNode node, float width,
                                       YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode)
        {
            Log.Info(ReactConstants.Tag, "[1] MeasureButton node=" + textNode.ReactTag + " with=" + width + " height=" + height + " content=" + _preparedSpannableText);
            // 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 task = DispatcherHelpers.CallOnDispatcher(() =>
            {
                var btnView = new Button(ReactProgram.RctWindow);

                var normalizedWidth  = YogaConstants.IsUndefined(width) ? double.PositiveInfinity : width;
                var normalizedHeight = YogaConstants.IsUndefined(height) ? double.PositiveInfinity : height;

                btnView.Resize((int)normalizedWidth, (int)normalizedHeight);
                btnView.Text = _preparedSpannableText;

                var btnPartObject = btnView.EdjeObject["elm.text"];
                if (btnPartObject == null)
                {
                    throw new Exception("Invalid Button.EdjeObject[\"elm.text\"]");
                }
                Size size = btnPartObject.TextBlockFormattedSize;
                Log.Info(ReactConstants.Tag, "[2] EDC conf info ={ width: " + size.Width + " height:" + size.Height + "}");
                btnView.Unrealize();

                return(MeasureOutput.Make(
                           (float)(size.Width + 80),
                           (float)(size.Height < 80 ? 80 : size.Height)));
            });

            return(task.Result);
        }
Exemple #19
0
        private static YogaSize MeasureProgressBar(YogaNode node, float width, YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode)
        {
            var adjustedHeight = YogaConstants.IsUndefined(height) ? 4f : height;

            return(MeasureOutput.Make(width, adjustedHeight));
        }