/// <summary>
        /// Main layout method
        /// </summary>
        /// <param name="width">Width to calculate the layout with</param>
        /// <param name="axis">0 for horizontal axis, 1 for vertical</param>
        /// <param name="layoutInput">If true, sets the layout input for the axis. If false, sets child position for axis</param>
        public float SetLayout(float width, int axis, bool layoutInput)
        {
            var groupHeight = rectTransform.rect.height;

            // Width that is available after padding is subtracted
            var workingWidth = rectTransform.rect.width - padding.left - padding.right;

            // Accumulates the total height of the rows, including spacing and padding.
            var yOffset = IsLowerAlign ? (float)padding.bottom : (float)padding.top;

            var currentRowWidth  = 0f;
            var currentRowHeight = 0f;

            for (var i = 0; i < rectChildren.Count; i++)
            {
                // LowerAlign works from back to front
                var index = IsLowerAlign ? rectChildren.Count - 1 - i : i;

                var child = rectChildren[index];

                var childWidth  = LayoutUtility.GetPreferredSize(child, 0);
                var childHeight = LayoutUtility.GetPreferredSize(child, 1);

                var childFlexibleWidth = LayoutUtility.GetFlexibleSize(child, 0);
                if (childFlexibleWidth > 0f)
                {
                    childWidth = workingWidth;
                }

                // Max child width is layout group with - padding
                childWidth = Mathf.Min(childWidth, workingWidth);

                // If adding this element would exceed the bounds of the row,
                // go to a new line after processing the current row
                if (currentRowWidth + childWidth > workingWidth)
                {
                    currentRowWidth -= Spacing;

                    // Process current row elements positioning
                    if (!layoutInput)
                    {
                        var h = CalculateRowVerticalOffset(groupHeight, yOffset, currentRowHeight);
                        LayoutRow(_rowList, currentRowWidth, currentRowHeight, workingWidth, padding.left, h, axis);
                    }

                    // Clear existing row
                    _rowList.Clear();

                    // Add the current row height to total height accumulator, and reset to 0 for the next row
                    yOffset += currentRowHeight;
                    yOffset += Spacing;

                    currentRowHeight = 0;
                    currentRowWidth  = 0;
                }

                currentRowWidth += childWidth;
                _rowList.Add(child);

                // We need the largest element height to determine the starting position of the next line
                if (childHeight > currentRowHeight)
                {
                    currentRowHeight = childHeight;
                }

                currentRowWidth += Spacing;
            }

            if (!layoutInput)
            {
                var h = CalculateRowVerticalOffset(groupHeight, yOffset, currentRowHeight);

                // Layout the final row
                LayoutRow(_rowList, currentRowWidth, currentRowHeight, workingWidth, padding.left, h, axis);
            }

            _rowList.Clear();

            // Add the last rows height to the height accumulator
            yOffset += currentRowHeight;
            yOffset += IsLowerAlign ? padding.top : padding.bottom;

            if (layoutInput)
            {
                if (axis == 1)
                {
                    SetLayoutInputForAxis(yOffset, yOffset, -1, axis);
                }
            }

            return(yOffset);
        }
示例#2
0
        public static Rect CalcSizeFromText(XdObjectJson xdObject, float?width)
        {
            var rawText = xdObject.Text.RawText;

            var font      = xdObject.Style.Font;
            var fontAsset = AssetDatabase.FindAssets($"{font.PostscriptName}")
                            .Select(guid => AssetDatabase.GUIDToAssetPath(guid))
                            .Select(path => AssetDatabase.LoadAssetAtPath <Object>(path))
                            .OfType <TMP_FontAsset>()
                            .Select(x =>
            {
                x.HasCharacters(rawText, out var missingCharacters);
                return(missingCharacters.Count, x);
            })
                            .OrderBy(x => x.Count)
                            .FirstOrDefault()
                            .x;

            if (fontAsset == null)
            {
                Debug.LogWarning($"TextMeshPro Asset {font.PostscriptName} is not found");
                var textParser = new TextObjectParser();
                return(textParser.CalcSize(xdObject));
            }

            var position = Vector2.zero;
            var fontSize = font.Size;

            position.y -= fontAsset.faceInfo.ascentLine * (fontSize / fontAsset.faceInfo.pointSize);

            var dummyObject        = new GameObject("Dummy");
            var dummyRectTransform = dummyObject.AddComponent <RectTransform>();

            dummyRectTransform.sizeDelta = new Vector2(width ?? 0f, 0f);

            var textMeshPro = dummyObject.AddComponent <TextMeshProUGUI>();

            textMeshPro.font     = fontAsset;
            textMeshPro.fontSize = fontSize;
            textMeshPro.text     = rawText;
            if (width != null)
            {
                textMeshPro.enableWordWrapping = true;
            }

            var size = new Vector2(LayoutUtility.GetPreferredSize(dummyRectTransform, 0), LayoutUtility.GetPreferredSize(dummyRectTransform, 1));

            DestroyImmediate(dummyObject);

            var lineJson = xdObject.Text.Paragraphs[0].Lines[0][0];

            position.x += lineJson.X;
            position.y += lineJson.Y;

            return(new Rect(position, size));
        }
        protected void LayoutRow(IList <RectTransform> contents, float rowWidth, float rowHeight, float maxWidth, float xOffset, float yOffset, int axis)
        {
            var xPos = xOffset;

            if (!ChildForceExpandWidth && IsCenterAlign)
            {
                xPos += (maxWidth - rowWidth) * 0.5f;
            }
            else if (!ChildForceExpandWidth && IsRightAlign)
            {
                xPos += (maxWidth - rowWidth);
            }

            var extraWidth = 0f;

            if (ChildForceExpandWidth)
            {
                extraWidth = (maxWidth - rowWidth) / _rowList.Count;
            }

            for (var j = 0; j < _rowList.Count; j++)
            {
                var index = IsLowerAlign ? _rowList.Count - 1 - j : j;

                var rowChild = _rowList[index];

                var rowChildWidth  = LayoutUtility.GetPreferredSize(rowChild, 0) + extraWidth;
                var rowChildHeight = LayoutUtility.GetPreferredSize(rowChild, 1);

                var childFlexibleWidth = LayoutUtility.GetFlexibleSize(rowChild, 0);
                if (childFlexibleWidth > 0f)
                {
                    rowChildWidth = rowWidth;
                }

                if (ChildForceExpandHeight)
                {
                    rowChildHeight = rowHeight;
                }

                rowChildWidth = Mathf.Min(rowChildWidth, maxWidth);

                var yPos = yOffset;

                if (IsMiddleAlign)
                {
                    yPos += (rowHeight - rowChildHeight) * 0.5f;
                }
                else if (IsLowerAlign)
                {
                    yPos += (rowHeight - rowChildHeight);
                }

                if (axis == 0)
                {
                    SetChildAlongAxis(rowChild, 0, xPos, rowChildWidth);
                }
                else
                {
                    SetChildAlongAxis(rowChild, 1, yPos, rowChildHeight);
                }

                xPos += rowChildWidth + Spacing;
            }
        }
示例#4
0
        protected void LayoutCol(IList <RectTransform> contents, float colWidth, float colHeight, float maxHeight, float xOffset, float yOffset, int axis)
        {
            var yPos = yOffset;

            if (!ChildForceExpandHeight && IsMiddleAlign)
            {
                yPos += (maxHeight - colHeight) * 0.5f;
            }
            else if (!ChildForceExpandHeight && IsLowerAlign)
            {
                yPos += (maxHeight - colHeight);
            }

            var extraHeight  = 0f;
            var extraSpacing = 0f;

            if (ChildForceExpandHeight)
            {
                extraHeight = (maxHeight - colHeight) / _itemList.Count;
            }
            else if (ExpandHorizontalSpacing)
            {
                extraSpacing = (maxHeight - colHeight) / (_itemList.Count - 1);
                if (_itemList.Count > 1)
                {
                    if (IsMiddleAlign)
                    {
                        yPos -= extraSpacing * 0.5f * (_itemList.Count - 1);
                    }
                    else if (IsLowerAlign)
                    {
                        yPos -= extraSpacing * (_itemList.Count - 1);
                    }
                }
            }

            for (var j = 0; j < _itemList.Count; j++)
            {
                var index = IsRightAlign ? _itemList.Count - 1 - j : j;

                var rowChild = _itemList[index];

                var rowChildWidth  = LayoutUtility.GetPreferredSize(rowChild, 0);
                var rowChildHeight = LayoutUtility.GetPreferredSize(rowChild, 1) + extraHeight;

                if (ChildForceExpandWidth)
                {
                    rowChildWidth = colWidth;
                }

                rowChildHeight = Mathf.Min(rowChildHeight, maxHeight);

                var xPos = xOffset;

                if (IsCenterAlign)
                {
                    xPos += (colWidth - rowChildWidth) * 0.5f;
                }
                else if (IsRightAlign)
                {
                    xPos += (colWidth - rowChildWidth);
                }

                //
                if (ExpandHorizontalSpacing && j > 0)
                {
                    yPos += extraSpacing;
                }

                if (axis == 0)
                {
                    SetChildAlongAxis(rowChild, 0, xPos, rowChildWidth);
                }
                else
                {
                    SetChildAlongAxis(rowChild, 1, yPos, rowChildHeight);
                }

                // Don't do vertical spacing for the last one
                if (j < _itemList.Count - 1)
                {
                    yPos += rowChildHeight + SpacingY;
                }
            }
        }
示例#5
0
        public override void OnPreviewGUI(Rect r, GUIStyle background)
        {
            if (Event.current.type != EventType.Repaint)
            {
                return;
            }

            if (m_Styles == null)
            {
                m_Styles = new Styles();
            }

            GameObject    go   = target as GameObject;
            RectTransform rect = go.transform as RectTransform;

            if (rect == null)
            {
                return;
            }

            // Apply padding
            RectOffset previewPadding = new RectOffset(-5, -5, -5, -5);

            r = previewPadding.Add(r);

            // Prepare rects for columns
            r.height = EditorGUIUtility.singleLineHeight;
            Rect labelRect  = r;
            Rect valueRect  = r;
            Rect sourceRect = r;

            labelRect.width  = kLabelWidth;
            valueRect.xMin  += kLabelWidth;
            valueRect.width  = kValueWidth;
            sourceRect.xMin += kLabelWidth + kValueWidth;

            // Headers
            GUI.Label(labelRect, "Property", m_Styles.headerStyle);
            GUI.Label(valueRect, "Value", m_Styles.headerStyle);
            GUI.Label(sourceRect, "Source", m_Styles.headerStyle);
            labelRect.y  += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
            valueRect.y  += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
            sourceRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;

            // Prepare reusable variable for out argument
            ILayoutElement source = null;

            // Show properties

            ShowProp(ref labelRect, ref valueRect, ref sourceRect, "Min Width", LayoutUtility.GetLayoutProperty(rect, e => e.minWidth, 0, out source).ToString(), source);
            ShowProp(ref labelRect, ref valueRect, ref sourceRect, "Min Height", LayoutUtility.GetLayoutProperty(rect, e => e.minHeight, 0, out source).ToString(), source);
            ShowProp(ref labelRect, ref valueRect, ref sourceRect, "Preferred Width", LayoutUtility.GetLayoutProperty(rect, e => e.preferredWidth, 0, out source).ToString(), source);
            ShowProp(ref labelRect, ref valueRect, ref sourceRect, "Preferred Height", LayoutUtility.GetLayoutProperty(rect, e => e.preferredHeight, 0, out source).ToString(), source);

            float flexible = 0;

            flexible = LayoutUtility.GetLayoutProperty(rect, e => e.flexibleWidth, 0, out source);
            ShowProp(ref labelRect, ref valueRect, ref sourceRect, "Flexible Width", flexible > 0 ? ("enabled (" + flexible.ToString() + ")") : "disabled", source);
            flexible = LayoutUtility.GetLayoutProperty(rect, e => e.flexibleHeight, 0, out source);
            ShowProp(ref labelRect, ref valueRect, ref sourceRect, "Flexible Height", flexible > 0 ? ("enabled (" + flexible.ToString() + ")") : "disabled", source);

            if (!rect.GetComponent <LayoutElement>())
            {
                Rect noteRect = new Rect(labelRect.x, labelRect.y + 10, r.width, EditorGUIUtility.singleLineHeight);
                GUI.Label(noteRect, "Add a LayoutElement to override values.", m_Styles.labelStyle);
            }
        }
示例#6
0
        /// <summary>
        /// Main layout method
        /// </summary>
        /// <param name="width">Width to calculate the layout with</param>
        /// <param name="axis">0 for horizontal axis, 1 for vertical</param>
        /// <param name="layoutInput">If true, sets the layout input for the axis. If false, sets child position for axis</param>
        public float SetLayout(int axis, bool layoutInput)
        {
            //container height and width
            var groupHeight = rectTransform.rect.height;
            var groupWidth  = rectTransform.rect.width;

            float spacingBetweenBars     = 0;
            float spacingBetweenElements = 0;
            float offset        = 0;
            float counterOffset = 0;
            float groupSize     = 0;
            float workingSize   = 0;

            if (startAxis == Axis.Horizontal)
            {
                groupSize   = groupHeight;
                workingSize = groupWidth - padding.left - padding.right;
                if (IsLowerAlign)
                {
                    offset        = (float)padding.bottom;
                    counterOffset = (float)padding.top;
                }
                else
                {
                    offset        = (float)padding.top;
                    counterOffset = (float)padding.bottom;
                }
                spacingBetweenBars     = SpacingY;
                spacingBetweenElements = SpacingX;
            }
            else if (startAxis == Axis.Vertical)
            {
                groupSize   = groupWidth;
                workingSize = groupHeight - padding.top - padding.bottom;
                if (IsRightAlign)
                {
                    offset        = (float)padding.right;
                    counterOffset = (float)padding.left;
                }
                else
                {
                    offset        = (float)padding.left;
                    counterOffset = (float)padding.right;
                }
                spacingBetweenBars     = SpacingX;
                spacingBetweenElements = SpacingY;
            }

            var currentBarSize  = 0f;
            var currentBarSpace = 0f;

            for (var i = 0; i < rectChildren.Count; i++)
            {
                int   index          = i;
                var   child          = rectChildren [index];
                float childSize      = 0;
                float childOtherSize = 0;
                //get height and width of elements.
                if (startAxis == Axis.Horizontal)
                {
                    if (invertOrder)
                    {
                        index = IsLowerAlign ? rectChildren.Count - 1 - i : i;
                    }
                    child          = rectChildren [index];
                    childSize      = LayoutUtility.GetPreferredSize(child, 0);
                    childSize      = Mathf.Min(childSize, workingSize);
                    childOtherSize = LayoutUtility.GetPreferredSize(child, 1);
                    childOtherSize = Mathf.Min(childOtherSize, workingSize);
                }
                else if (startAxis == Axis.Vertical)
                {
                    if (invertOrder)
                    {
                        index = IsRightAlign ? rectChildren.Count - 1 - i : i;
                    }
                    child          = rectChildren [index];
                    childSize      = LayoutUtility.GetPreferredSize(child, 1);
                    childSize      = Mathf.Min(childSize, workingSize);
                    childOtherSize = LayoutUtility.GetPreferredSize(child, 0);
                    childOtherSize = Mathf.Min(childOtherSize, workingSize);
                }

                // If adding this element would exceed the bounds of the container,
                // go to a new bar after processing the current bar
                if (currentBarSize + childSize > workingSize)
                {
                    currentBarSize -= spacingBetweenElements;

                    // Process current bar elements positioning
                    if (!layoutInput)
                    {
                        if (startAxis == Axis.Horizontal)
                        {
                            float newOffset = CalculateRowVerticalOffset(groupSize, offset, currentBarSpace);
                            LayoutRow(_itemList, currentBarSize, currentBarSpace, workingSize, padding.left, newOffset, axis);
                        }
                        else if (startAxis == Axis.Vertical)
                        {
                            float newOffset = CalculateColHorizontalOffset(groupSize, offset, currentBarSpace);
                            LayoutCol(_itemList, currentBarSpace, currentBarSize, workingSize, newOffset, padding.top, axis);
                        }
                    }

                    // Clear existing bar
                    _itemList.Clear();

                    // Add the current bar space to total barSpace accumulator, and reset to 0 for the next row
                    offset += currentBarSpace;
                    offset += spacingBetweenBars;

                    currentBarSpace = 0;
                    currentBarSize  = 0;
                }

                currentBarSize += childSize;
                _itemList.Add(child);

                // We need the largest element height to determine the starting position of the next line
                if (childOtherSize > currentBarSpace)
                {
                    currentBarSpace = childOtherSize;
                }

                // Don't do this for the last one
                if (i < rectChildren.Count - 1)
                {
                    currentBarSize += spacingBetweenElements;
                }
            }

            // Layout the final bar
            if (!layoutInput)
            {
                if (startAxis == Axis.Horizontal)
                {
                    float newOffset = CalculateRowVerticalOffset(groupHeight, offset, currentBarSpace);
                    currentBarSize -= spacingBetweenElements;
                    LayoutRow(_itemList, currentBarSize, currentBarSpace, workingSize - (ChildForceExpandWidth ? 0 : spacingBetweenElements), padding.left, newOffset, axis);
                }
                else if (startAxis == Axis.Vertical)
                {
                    float newOffset = CalculateColHorizontalOffset(groupWidth, offset, currentBarSpace);
                    currentBarSize -= spacingBetweenElements;
                    LayoutCol(_itemList, currentBarSpace, currentBarSize, workingSize - (ChildForceExpandHeight ? 0 : spacingBetweenElements), newOffset, padding.top, axis);
                }
            }

            _itemList.Clear();

            // Add the last bar space to the barSpace accumulator
            offset += currentBarSpace;
            offset += counterOffset;

            if (layoutInput)
            {
                SetLayoutInputForAxis(offset, offset, -1, axis);
            }
            return(offset);
        }
示例#7
0
        public void ShowBlockCategory(string categoryName)
        {
            Debug.Log("ShowBlockCategory");
            Game.sound.play("CLICK");
            if (string.Equals(categoryName, mActiveCategory))
            {
                return;
            }

            if (!m_BlockScrollList.activeInHierarchy)
            {
                m_BlockScrollList.SetActive(true);
            }

            if (!string.IsNullOrEmpty(mActiveCategory))
            {
                mRootList[mActiveCategory].SetActive(false);
            }

            mActiveCategory = categoryName;

            GameObject    contentObj;
            RectTransform contentTrans;

            if (mRootList.TryGetValue(categoryName, out contentObj))
            {
                contentObj.SetActive(true);
                contentTrans = contentObj.transform as RectTransform;
            }
            else
            {
                contentObj      = GameObject.Instantiate(m_BlockContentPrefab, m_BlockContentPrefab.transform.parent);
                contentObj.name = "Content_" + categoryName;
                contentObj.SetActive(true);
                mRootList[categoryName] = contentObj;

                contentTrans = contentObj.GetComponent <RectTransform>();

                //build new blocks
                if (categoryName.Equals(Define.VARIABLE_CATEGORY_NAME))
                {
                    BuildVariableBlocks();
                }
                else if (categoryName.Equals(Define.PROCEDURE_CATEGORY_NAME))
                {
                    BuildProcedureBlocks();
                }
                else
                {
                    BuildBlockViewsForActiveCategory();
                }
            }

            //resize the background
            LayoutRebuilder.ForceRebuildLayoutImmediate(contentTrans);
            m_BlockScrollList.GetComponent <RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, LayoutUtility.GetPreferredWidth(contentTrans));

            m_BlockScrollList.GetComponent <ScrollRect>().content = contentTrans;
        }
示例#8
0
        /// <summary>
        /// Creates a string recursively describing the specified GameObject.
        /// </summary>
        /// <param name="root">The root GameObject hierarchy.</param>
        /// <param name="indent">The indentation to use.</param>
        /// <returns>A string describing this game object.</returns>
        private static string GetObjectTree(GameObject root, int indent)
        {
            var result = new StringBuilder(1024);
            // Calculate indent to make nested reading easier
            var solBuilder = new StringBuilder(indent);

            for (int i = 0; i < indent; i++)
            {
                solBuilder.Append(' ');
            }
            string sol       = solBuilder.ToString();
            var    transform = root.transform;
            int    n         = transform.childCount;

            // Basic information
            result.Append(sol).AppendFormat("GameObject[{0}, {1:D} child(ren), Layer {2:D}, " +
                                            "Active={3}]", root.name, n, root.layer, root.activeInHierarchy).AppendLine();
            // Transformation
            result.Append(sol).AppendFormat(" Translation={0} [{3}] Rotation={1} [{4}] " +
                                            "Scale={2}", transform.position, transform.rotation, transform.
                                            localScale, transform.localPosition, transform.localRotation).AppendLine();
            // Components
            foreach (var component in root.GetComponents <Component>())
            {
                if (component is RectTransform rt)
                {
                    // UI rectangle
                    Vector2 size = rt.sizeDelta;
                    result.Append(sol).AppendFormat(" Rect[Size=({0:F2},{1:F2}) Min=" +
                                                    "({2:F2},{3:F2}) ", size.x, size.y, LayoutUtility.GetMinWidth(rt),
                                                    LayoutUtility.GetMinHeight(rt));
                    result.AppendFormat("Preferred=({0:F2},{1:F2}) Flexible=({2:F2}," +
                                        "{3:F2})]", LayoutUtility.GetPreferredWidth(rt), LayoutUtility.
                                        GetPreferredHeight(rt), LayoutUtility.GetFlexibleWidth(rt),
                                        LayoutUtility.GetFlexibleHeight(rt)).AppendLine();
                }
                else if (component != null && !(component is Transform))
                {
                    // Exclude destroyed components and Transform objects
                    result.Append(sol).Append(" Component[").Append(component.GetType().
                                                                    FullName);
                    AddComponentText(result, component);
                    result.AppendLine("]");
                }
            }
            // Children
            if (n > 0)
            {
                result.Append(sol).AppendLine(" Children:");
            }
            for (int i = 0; i < n; i++)
            {
                var child = transform.GetChild(i).gameObject;
                if (child != null)
                {
                    // Exclude destroyed objects
                    result.AppendLine(GetObjectTree(child, indent + 2));
                }
            }
            return(result.ToString().TrimEnd());
        }
示例#9
0
 public static Vector2 GetPreferredSize(this RectTransform rectTransform)
 {
     return(new Vector2(
                LayoutUtility.GetPreferredSize(rectTransform, 0),
                LayoutUtility.GetPreferredSize(rectTransform, 1)));
 }
示例#10
0
        public GameObject Build()
        {
            var textField = PUIElements.CreateUI(null, Name);
            var style     = TextStyle ?? PUITuning.Fonts.TextLightStyle;
            // Background
            var border = textField.AddComponent <Image>();

            border.sprite = PUITuning.Images.BoxBorderWhite;
            border.type   = Image.Type.Sliced;
            border.color  = style.textColor;
            // Text box with rectangular clipping area
            var textArea = PUIElements.CreateUI(textField, "Text Area", false);

            textArea.AddComponent <Image>().color = BackColor;
            var mask = textArea.AddComponent <RectMask2D>();
            // Scrollable text
            var textBox = PUIElements.CreateUI(textArea, "Text");
            // Text to display
            var textDisplay = ConfigureField(textBox.AddComponent <TextMeshProUGUI>(), style,
                                             TextAlignment);

            textDisplay.enableWordWrapping = false;
            textDisplay.maxVisibleLines    = 1;
            textDisplay.raycastTarget      = true;
            // Text field itself
            textField.SetActive(false);
            var textEntry = textField.AddComponent <TMP_InputField>();

            textEntry.textComponent = textDisplay;
            textEntry.textViewport  = textArea.rectTransform();
            textEntry.text          = Text ?? "";
            textDisplay.text        = Text ?? "";
            // Placeholder
            if (PlaceholderText != null)
            {
                var placeholder = PUIElements.CreateUI(textArea, "Placeholder Text");
                var textPlace   = ConfigureField(placeholder.AddComponent <TextMeshProUGUI>(),
                                                 PlaceholderStyle ?? style, TextAlignment);
                textPlace.maxVisibleLines = 1;
                textPlace.text            = PlaceholderText;
                textEntry.placeholder     = textPlace;
            }
            // Events!
            ConfigureTextEntry(textEntry);
            var events = textField.AddComponent <PTextFieldEvents>();

            events.OnTextChanged = OnTextChanged;
            events.OnValidate    = OnValidate;
            events.TextObject    = textBox;
            // Add tooltip
            PUIElements.SetToolTip(textField, ToolTip);
            mask.enabled = true;
            PUIElements.SetAnchorOffsets(textBox, new RectOffset());
            textField.SetActive(true);
            // Lay out
            var rt = textBox.rectTransform();

            LayoutRebuilder.ForceRebuildLayoutImmediate(rt);
            var layout = PUIUtils.InsetChild(textField, textArea, Vector2.one, new Vector2(
                                                 MinWidth, LayoutUtility.GetPreferredHeight(rt))).AddOrGet <LayoutElement>();

            layout.flexibleWidth  = FlexSize.x;
            layout.flexibleHeight = FlexSize.y;
            OnRealize?.Invoke(textField);
            return(textField);
        }