Exemplo n.º 1
0
        /**
         *      create line of contents -> sort all content by base line.
         */
        private HandlePoint SortByLayoutLine(List <VirtualGameObject> layoutLine, HandlePoint handlePoint)
        {
            // find tallest content in layoutLine.
            var targetHeightObjArray = layoutLine.OrderByDescending(c => c.vRectTransform.vSizeDelta.y + c.padding.PadHeight()).ToArray();

            if (0 < targetHeightObjArray.Length)
            {
                var tallestContent = targetHeightObjArray[0];

                // get tallest padded height. this will be this layoutLine's bottom line.
                var paddedHighestHeightInLine = tallestContent.vRectTransform.vSizeDelta.y + tallestContent.padding.PadHeight();

                // other child content will be moved.
                var skipFirst = true;
                foreach (var childInLine in targetHeightObjArray)
                {
                    if (skipFirst)
                    {
                        skipFirst = false;
                        continue;
                    }

                    var childPaddedHeight = childInLine.vRectTransform.vSizeDelta.y + childInLine.padding.PadHeight();
                    var heightDiff        = paddedHighestHeightInLine - childPaddedHeight;
                    childInLine.vRectTransform.vAnchoredPosition += new Vector2(0, heightDiff);

                    // Debug.LogError("childInLine:" + childInLine.tag + " childInLine.rectTransform.anchoredPosition:" + childInLine.rectTransform.anchoredPosition + " under tag:" + this.tag + " heightDiff:" + heightDiff);
                }

                // set next line head.
                handlePoint.nextLeftHandle = 0;
                handlePoint.nextTopHandle  = tallestContent.vRectTransform.vAnchoredPosition.y + tallestContent.vRectTransform.vSizeDelta.y + tallestContent.padding.PadHeight();
                // Debug.LogError("SortByLayoutLine handlePoint.nextTopHandle:" + handlePoint.nextTopHandle);
                // Debug.LogError("SortByLayoutLine rectTransform.anchoredPosition:" + rectTransform.anchoredPosition + " of tag:" + tag + " handlePoint:" + handlePoint.nextTopHandle);
            }

            return(handlePoint);
        }
Exemplo n.º 2
0
        /**
         *      return generated game object.
         */
        public GameObject MaterializeRoot(string viewName, Vector2 viewPort, Tokenizer.OnLayoutDelegate onLayoutDel, Tokenizer.OnMaterializeDelegate onMaterializeDel)
        {
            var rootHandlePoint = new HandlePoint(0, 0, viewPort.x, viewPort.y);

            // 事前計算、ここでコンテンツの一覧を返すようにすればいいかな。要素単位で。
            Layout(this, rootHandlePoint, onLayoutDel, t => {});


            this._gameObject = new GameObject(viewName + Tag.ROOT.ToString());

            this.rootInstance = this._gameObject.AddComponent <InformationRootMonoBehaviour>();
            var rectTrans = this._gameObject.AddComponent <RectTransform>();

            rectTrans.anchorMin = Vector2.up;
            rectTrans.anchorMax = Vector2.up;
            rectTrans.pivot     = Vector2.up;
            rectTrans.position  = Vector2.zero;
            rectTrans.sizeDelta = viewPort;

            // 範囲指定してGOを充てる、ということがしたい。
            Materialize(this, onMaterializeDel);

            return(this._gameObject);
        }
Exemplo n.º 3
0
        private void LayoutChildlen(List <VirtualGameObject> childlen, HandlePoint handlePoint, Tokenizer.OnLayoutDelegate onLayoutDel)
        {
            // Debug.LogWarning("LayoutChildlen、子供にいくに従って、親要素の起点から幅と高さの制限をつける必要がある。");
            // Debug.LogError("handlePoint.nextLeftHandle:" + handlePoint.nextLeftHandle);
            var childHandlePoint = new HandlePoint(0, 0, handlePoint.viewWidth, handlePoint.viewHeight);

            // layout -> resize -> padding of childlen.

            var layoutLine = new List <VirtualGameObject>();
            var i          = 0;

            while (true)
            {
                if (childlen.Count <= i)
                {
                    break;
                }

                var child = childlen[i];

                // consume br as linefeed.
                if (child.tag == Tag.BR)
                {
                    // Debug.LogError("brが発生するので、handlePointのyは変わってるはず:" + handlePoint.nextTopHandle);
                    childHandlePoint = SortByLayoutLine(layoutLine, childHandlePoint);
                    // Debug.LogError("brが発生したので、handlePointのyは変わってるはず:" + handlePoint.nextTopHandle);

                    // forget current line.
                    layoutLine.Clear();

                    // set next line.
                    childHandlePoint.nextLeftHandle = 0;
                    i++;
                    continue;
                }

                // Debug.LogWarning("hr、これ下の方でまとめて処理できるかも。");
                // consume hr 1/2 as horizontal rule.
                if (child.tag == Tag.HR)
                {
                    childHandlePoint = SortByLayoutLine(layoutLine, childHandlePoint);

                    // forget current line.
                    layoutLine.Clear();
                }


                var sortLayoutLineBeforeLining = false;
                var sortLayoutLineAfterLining  = false;


                /*
                 *      insert content to childlen list.
                 *      create new content from one long content by length overflow.
                 */
                Action <List <VirtualGameObject> > insertAct = insertNewVGameObject => {
                    childlen.InsertRange(i + 1, insertNewVGameObject);

                    // this line is ended at this content. need layout.
                    sortLayoutLineAfterLining = true;
                };

                // set position and calculate size.
                childHandlePoint = child.Layout(this, childHandlePoint, onLayoutDel, insertAct);

                // consume hr 2/2 as horizontal rule.
                if (child.tag == Tag.HR)
                {
                    // set next line.
                    childHandlePoint.nextLeftHandle = 0;
                    i++;
                    continue;
                }

                // root content does not request sorting child contents.
                if (this.tag == Tag.ROOT)
                {
                    i++;
                    continue;
                }


                /*
                 *      the insertAct(t) is raised or not raised.
                 */

                // if child is content and that width is 0, this is because, there is not enough width in this line.
                // line is ended.
                if (child.tag == Tag._CONTENT && child.vRectTransform.vSizeDelta.x == 0)
                {
                    sortLayoutLineAfterLining = true;
                }


                /*
                 *      nested bq.
                 */
                if (this.tag == Tag.BLOCKQUOTE)
                {
                    // nested bq.
                    if (child.tag == Tag.BLOCKQUOTE)
                    {
                        sortLayoutLineBeforeLining = true;
                    }
                }

                /*
                 *      nested list's child list should be located to new line.
                 */
                if (this.tag == Tag.LI)
                {
                    // nested list.
                    if (child.tag == Tag.OL || child.tag == Tag.UL)
                    {
                        sortLayoutLineBeforeLining = true;
                    }
                }

                // list's child should be ordered vertically.
                if (this.tag == Tag.OL || this.tag == Tag.UL)
                {
                    sortLayoutLineAfterLining = true;
                }

                // check width overflow.
                // if next left handle is overed, sort as lined contents.
                if (childHandlePoint.viewWidth < childHandlePoint.nextLeftHandle)
                {
                    sortLayoutLineBeforeLining = true;
                }

                // table
                {
                    if (child.tag == Tag.THEAD)                      // table head is single line.
                    {
                        sortLayoutLineAfterLining = true;
                    }
                    else if (child.tag == Tag.TR)                        // table row.
                    {
                        sortLayoutLineAfterLining = true;
                    }
                }

                /*
                 *      sort current lined contents as 1 line of contents.
                 *      before adding current content.
                 */
                if (sortLayoutLineBeforeLining)
                {
                    childHandlePoint = SortByLayoutLine(layoutLine, childHandlePoint);

                    // forget current line.
                    layoutLine.Clear();

                    // move current child content to next line head.
                    child.vRectTransform.vAnchoredPosition = new Vector2(childHandlePoint.nextLeftHandle + child.padding.left, childHandlePoint.nextTopHandle + child.padding.top);
                    // Debug.LogError("child.rectTransform.anchoredPosition:" + child.rectTransform.anchoredPosition);

                    // set next handle.
                    childHandlePoint.nextLeftHandle = childHandlePoint.nextLeftHandle + child.padding.left + child.vRectTransform.vSizeDelta.x + child.padding.right;
                }

                // content width is smaller than viewpoint width.
                layoutLine.Add(child);

                /*
                 *      sort current lined contents as 1 line of contents.
                 *      after adding current content.
                 *
                 *      this line is ended by this content.
                 */
                if (sortLayoutLineAfterLining)
                {
                    childHandlePoint = SortByLayoutLine(layoutLine, childHandlePoint);

                    // forget current line.
                    layoutLine.Clear();

                    // set next content's head position.
                    childHandlePoint.nextLeftHandle = 0;
                }

                i++;
            }

            // if layoutLine content is exist, re-layout all in 1 line.
            if (0 < layoutLine.Count)
            {
                childHandlePoint = SortByLayoutLine(layoutLine, childHandlePoint);
            }
        }
Exemplo n.º 4
0
        /**
         *      layout contents.
         *
         *      set position and size of content.
         */
        private HandlePoint Layout(VirtualGameObject parent, HandlePoint handlePoint, Tokenizer.OnLayoutDelegate onLayoutDel, Action <List <VirtualGameObject> > insert)
        {
            switch (this.tag)
            {
            case Tag.ROOT: {
                // do nothing.
                break;
            }

            default: {
                LayoutTagContent(handlePoint.nextLeftHandle, handlePoint.nextTopHandle, handlePoint.viewWidth, handlePoint.viewHeight, insert);
                break;
            }
            }

            // parent layout is done. will be resized by child, then padding.


            var childlen = this.transform.GetChildlen();

            if (0 < childlen.Count)
            {
                LayoutChildlen(childlen, handlePoint, onLayoutDel);

                /*
                 * set parent = this content's size to wrapping all childlen.
                 */
                var rightBottomPoint = Vector2.zero;

                // fit most large bottom-right point. largest point of width and y.
                foreach (var child in childlen)
                {
                    var paddedRightBottomPoint = child.PaddedRightBottomPoint();

                    if (rightBottomPoint.x < paddedRightBottomPoint.x)
                    {
                        rightBottomPoint.x = paddedRightBottomPoint.x;
                    }
                    if (rightBottomPoint.y < paddedRightBottomPoint.y)
                    {
                        rightBottomPoint.y = paddedRightBottomPoint.y;
                    }
                }

                // fit size to wrap all child contents.
                vRectTransform.vSizeDelta = rightBottomPoint;


                // calculate table's contents.
                if (this.tag == Tag.TABLE)
                {
                    /*
                     *      all contents size calculation inside this table is done.
                     *      count up row,
                     *      find longest content,
                     *      and adjust left point of contents.
                     */
                    var tableLayoutRecord = new TableLayoutRecord();

                    // countup rows.
                    foreach (var tableChild in this.transform.GetChildlen())
                    {
                        CollectTableContentRowCountRecursively(tableChild, tableLayoutRecord);
                    }

                    // find longest content.
                    foreach (var tableChild in this.transform.GetChildlen())
                    {
                        CollectTableContentRowMaxWidthsRecursively(tableChild, tableLayoutRecord);
                    }

                    // resize & reset position of this table contents by calculated record.
                    foreach (var tableChild in this.transform.GetChildlen())
                    {
                        SetupTableContentPositionRecursively(tableChild, tableLayoutRecord);
                    }
                }
            }

            /*
             *      set padding if need.
             *      default padding is 0.
             */
            onLayoutDel(this.tag, this.depth, this.padding, this.keyValueStore);

            /*
             *      adopt padding to this content.
             */
            {
                // translate anchor position of content.(child follows parent.)
                vRectTransform.vAnchoredPosition += padding.LeftTopPoint();

                handlePoint.nextLeftHandle += padding.PadWidth();
                handlePoint.nextTopHandle  += padding.PadHeight();
                // Debug.LogWarning("実験した方が良さそう");
            }
            // Debug.LogError("rectTransform.anchoredPosition:" + rectTransform.anchoredPosition);

            /*
             *      set next left-top point by parent tag kind.
             */
            switch (parent.tag)
            {
            default: {
                // 回り込みを実現する。んだけど、これはどちらかというと多数派で、デフォルトっぽい。
                // next content is planned to layout to the next of this content.
                handlePoint.nextLeftHandle = this.vRectTransform.vAnchoredPosition.x + this.vRectTransform.vSizeDelta.x + this.padding.PadWidth();                        // right edge with padding
                // Debug.LogError("handlePoint.nextLeftHandle:" + handlePoint.nextLeftHandle);
                break;
            }

            // Rootコンテンツにぶらさがっている項目は、全てCRLFがかかる。
            case Tag.ROOT: {
                // CRLF
                handlePoint.nextLeftHandle = 0;
                handlePoint.nextTopHandle += this.vRectTransform.vSizeDelta.y + this.padding.PadHeight();

                // Debug.LogError("親がRootなので、改行する。handlePoint.nextTopHandle:" + handlePoint.nextTopHandle + " of tag:" + tag + " rectTransform.anchoredPosition:" + this.rectTransform.anchoredPosition);
                break;
            }
            }

            return(handlePoint);
        }
Exemplo n.º 5
0
        /**
         *      layout contents.
         *
         *      set position and size of content.
         */
        private HandlePoint Layout(VirtualGameObject parent, HandlePoint handlePoint, Tokenizer.OnLayoutDelegate onLayoutDel, Action <List <VirtualGameObject> > insert)
        {
            switch (this.tag)
            {
            case Tag.ROOT: {
                // do nothing.
                break;
            }

            default: {
                // Debug.LogError("before layout rectTransform.anchoredPosition:" + rectTransform.anchoredPosition + " of tag:" + tag + " handlePoint:" + handlePoint.nextTopHandle);
                LayoutTagContent(handlePoint.nextLeftHandle, handlePoint.nextTopHandle, handlePoint.viewWidth, handlePoint.viewHeight, insert);
                // Debug.LogError("after layout rectTransform.anchoredPosition:" + rectTransform.anchoredPosition + " of tag:" + tag + " handlePoint:" + handlePoint.nextTopHandle);
                break;
            }
            }

            // parent layout is done. will be resized by child, then padding.

            // calculate table's column count.
            if (this.tag == Tag.TABLE)
            {
                // ハンドラで、n x m のテーブルであることが通知できる。
                // 別の話、N文字目に改行があったことが記録として残せるので、要素にidを振ることができる。
                // n x mがわかったら、それぞれの幅をどうしたいかを通知できるはず。
                // 指定したら、その幅を採用する。レイアウトも溢れも。ということはできそう。

                // ッツー感じか。n単位でwidthを返せばいいので、nを受け取ってn x widthを返すのでよさげ。
                var maxPoints = new MaxPoints();

                // pre-layout table contents.
                foreach (var tableChild in this.transform.GetChildlen())
                {
                    DoLayoutTagContentRecursively(tableChild, handlePoint.nextLeftHandle, handlePoint.nextTopHandle, handlePoint.viewWidth, handlePoint.viewHeight, maxPoints);
                }
            }


            var childlen = this.transform.GetChildlen();

            if (0 < childlen.Count)
            {
                LayoutChildlen(childlen, handlePoint, onLayoutDel);

                /*
                 * set parent = this content's size to wrapping all childlen.
                 */
                var rightBottomPoint = Vector2.zero;

                // fit most large bottom-right point. largest point of width and y.
                foreach (var child in childlen)
                {
                    var paddedRightBottomPoint = child.PaddedRightBottomPoint();

                    if (rightBottomPoint.x < paddedRightBottomPoint.x)
                    {
                        rightBottomPoint.x = paddedRightBottomPoint.x;
                    }
                    if (rightBottomPoint.y < paddedRightBottomPoint.y)
                    {
                        rightBottomPoint.y = paddedRightBottomPoint.y;
                    }
                }

                // fit size to wrap all child contents.
                rectTransform.sizeDelta = rightBottomPoint;
                // Debug.LogError("set wrap rectTransform.sizeDelta:" + rectTransform.sizeDelta + " of tag:" + tag);
                // Debug.LogError("after wrap rectTransform.anchoredPosition:" + rectTransform.anchoredPosition + " of tag:" + tag + " handlePoint:" + handlePoint.nextTopHandle);
                // layout and padding and orientation of child tags are done.
            }

            /*
             *      set padding if need.
             *      default padding is 0.
             */
            onLayoutDel(this.tag, this.depth, this.padding, this.keyValueStore);

            /*
             *      adopt padding to this content.
             */
            {
                // translate anchor position of content.(child follows parent.)
                rectTransform.anchoredPosition += padding.LeftTopPoint();

                handlePoint.nextLeftHandle += padding.PadWidth();
                handlePoint.nextTopHandle  += padding.PadHeight();
                // Debug.LogWarning("実験した方が良さそう");
            }
            // Debug.LogError("rectTransform.anchoredPosition:" + rectTransform.anchoredPosition);

            /*
             *      set next left-top point by parent tag kind.
             */
            switch (parent.tag)
            {
            default: {
                // 回り込みを実現する。んだけど、これはどちらかというと多数派で、デフォルトっぽい。
                // next content is planned to layout to the next of this content.
                handlePoint.nextLeftHandle = this.rectTransform.anchoredPosition.x + this.rectTransform.sizeDelta.x + this.padding.PadWidth();                        // right edge with padding
                // Debug.LogError("handlePoint.nextLeftHandle:" + handlePoint.nextLeftHandle);
                break;
            }

            // Rootコンテンツにぶらさがっている項目は、全てCRLFがかかる。
            case Tag.ROOT: {
                // CRLF
                handlePoint.nextLeftHandle = 0;
                handlePoint.nextTopHandle += this.rectTransform.sizeDelta.y + this.padding.PadHeight();

                // Debug.LogError("親がRootなので、改行する。handlePoint.nextTopHandle:" + handlePoint.nextTopHandle + " of tag:" + tag + " rectTransform.anchoredPosition:" + this.rectTransform.anchoredPosition);
                break;
            }
            }

            return(handlePoint);
        }