Exemplo n.º 1
0
        private void SetupTableContentPositionRecursively(VirtualGameObject child, TableLayoutRecord tableLayoutRecord)
        {
            // overwrite parent content width of TH and TD.
            if (child.tag == Tag.THEAD || child.tag == Tag.TBODY || child.tag == Tag.THEAD || child.tag == Tag.TR)
            {
                var width = tableLayoutRecord.TotalWidth();
                child.vRectTransform.vSizeDelta = new Vector2(width, child.vRectTransform.vSizeDelta.y);
            }

            /*
             *      change TH, TD content's x position and width.
             *      x position -> 0, 1st row's longest content len, 2nd row's longest content len,...
             *      width -> 1st row's longest content len, 2nd row's longest content len,...
             */
            if (child.tag == Tag.TH || child.tag == Tag.TD)
            {
                var offsetAndWidth = tableLayoutRecord.GetOffsetAndWidth();

                child.vRectTransform.vAnchoredPosition = new Vector2(offsetAndWidth.offset, child.vRectTransform.vAnchoredPosition.y);
                child.vRectTransform.vSizeDelta        = new Vector2(offsetAndWidth.width, child.vRectTransform.vSizeDelta.y);
            }

            foreach (var nestedChild in child.transform.GetChildlen())
            {
                child.SetupTableContentPositionRecursively(nestedChild, tableLayoutRecord);
            }
        }
Exemplo n.º 2
0
        private void CollectTableContentRowCountRecursively(VirtualGameObject child, TableLayoutRecord tableLayoutRecord)
        {
            // count up table header count.
            if (child.tag == Tag.TH)
            {
                tableLayoutRecord.IncrementRow();
            }

            foreach (var nestedChild in child.transform.GetChildlen())
            {
                child.CollectTableContentRowCountRecursively(nestedChild, tableLayoutRecord);
            }
        }
Exemplo n.º 3
0
        private void DoLayoutTagContentRecursively(VirtualGameObject child, float offsetX, float offsetY, float viewWidth, float viewHeight, MaxPoints maxPoints)
        {
            if (child.tag == Tag.TH)
            {
                maxPoints.AddXCount();
            }

            // もし子供ゾーンに入ったら、その時点でmaxPointの値を指定していいはず。
            // で。それを抜けたら、場で保持しているパラメータを、viewWidthとして指定できる!

            child.LayoutTagContent(offsetX, offsetY, viewWidth, viewHeight, (a) => {});

            foreach (var nestedChild in child.transform.GetChildlen())
            {
                child.DoLayoutTagContentRecursively(nestedChild, offsetX, offsetY, viewWidth, viewHeight, maxPoints);
            }
        }
Exemplo n.º 4
0
            public TagPoint(Tag tag, string parentRawTag, Tag[] depth, Dictionary <KV_KEY, string> kv, string originalTagName)
            {
                this.tag             = tag;
                this.depth           = depth;
                this.originalTagName = originalTagName;

                var prefabName = string.Empty;

                switch (tag)
                {
                case Tag._CONTENT: {
                    prefabName = parentRawTag;
                    break;
                }

                // these are container.
                case Tag.EM:
                case Tag.STRONG:
                case Tag.PRE:
                case Tag.BLOCKQUOTE:
                case Tag.CODE:
                case Tag.H:
                case Tag.P:
                case Tag.A:
                case Tag.UL:
                case Tag.LI:
                case Tag.OL:
                case Tag.TABLE:
                case Tag.THEAD:
                case Tag.TBODY:
                case Tag.TR:
                case Tag.TH:
                case Tag.TD: {                        // these are container.
                    prefabName = originalTagName.ToUpper() + "Container";
                    break;
                }

                default: {
                    prefabName = originalTagName.ToUpper();
                    break;
                }
                }

                this.vGameObject = new VirtualGameObject(tag, depth, kv, prefabName);
            }
Exemplo n.º 5
0
        private void CollectTableContentRowMaxWidthsRecursively(VirtualGameObject child, TableLayoutRecord tableLayoutRecord)
        {
            var total = 0f;

            foreach (var nestedChild in child.transform.GetChildlen())
            {
                child.CollectTableContentRowMaxWidthsRecursively(nestedChild, tableLayoutRecord);
                if (child.tag == Tag.TH || child.tag == Tag.TD)
                {
                    var nestedChildContentWidth = nestedChild.vRectTransform.vSizeDelta.x;
                    total += nestedChildContentWidth;
                }
            }

            if (child.tag == Tag.TH || child.tag == Tag.TD)
            {
                tableLayoutRecord.UpdateMaxWidth(total);
            }
        }
Exemplo n.º 6
0
        private void Materialize(VirtualGameObject parent, Tokenizer.OnMaterializeDelegate onMaterializeDel)
        {
            switch (this.tag)
            {
            case Tag.ROOT: {
                // do nothing.
                break;
            }

            case Tag.BR: {
                // has no child. no visual. do nothing.
                break;
            }

            default: {
                this._gameObject = MaterializeTagContent();
                this._gameObject.transform.SetParent(parent._gameObject.transform, false);
                var rectTrans = this._gameObject.GetComponent <RectTransform>();
                if (rectTrans == null)
                {
                    return;
                }

                // set position. convert layout position to uGUI position system.
                rectTrans.anchoredPosition = new Vector2(rectTransform.anchoredPosition.x, -rectTransform.anchoredPosition.y);
                // Debug.LogError("materialize rectTrans.anchoredPosition:" + rectTrans.anchoredPosition);
                rectTrans.sizeDelta = rectTransform.sizeDelta;

                break;
            }
            }

            foreach (var child in this.transform.GetChildlen())
            {
                child.Materialize(this, onMaterializeDel);
            }

            onMaterializeDel(this._gameObject, this.tag, this.depth, new Dictionary <KV_KEY, string>(this.keyValueStore));
        }
Exemplo n.º 7
0
        public Tokenizer(string source)
        {
            var root = new TagPoint(Tag.ROOT, string.Empty, new Tag[0], new Dictionary <KV_KEY, string>(), string.Empty);

            rootObject = Tokenize(root, source.Replace("\n", string.Empty));
        }
Exemplo n.º 8
0
        private ContentAndWidthAndHeight LayoutTextContent(float offset, string text, float contentWidth, float contentHeight, Action <List <VirtualGameObject> > insert)
        {
            // このあたりをhttpリクエストに乗っけるようなことができるとなおいいのだろうか。AssetBundleともちょっと違う何か、的な。

            /*
             *      ・Resourcesに置ける
             *      ・AssetBundle化できる
             */
            var prefab = LoadPrefab(prefabName);

            if (prefab == null)
            {
                return(new ContentAndWidthAndHeight());
            }

            // Debug.LogError("prefabName:" + prefabName);

            // use prefab's text component for using it's text setting.
            var textComponent = prefab.GetComponent <Text>();

            if (textComponent == null)
            {
                throw new Exception("failed to get Text component from prefab:" + prefabName);
            }

            // set content first.
            textComponent.text = text;

            // Debug.LogError("offset:" + offset + " text:" + text);

            var generator = new TextGenerator();

            var setting = textComponent.GetGenerationSettings(new Vector2(contentWidth - offset, contentHeight));

            generator.Populate(text, setting);

            var lines    = new List <string>();
            var nextText = text;            // get copy.

            if (generator.lineCount == 0)
            {
                // no line layouted. set this text to next line.
                var nextLineVGameObject = new VirtualGameObject(
                    this.tag,
                    this.depth,
                    new Dictionary <KV_KEY, string>()
                {
                    { KV_KEY._CONTENT, nextText }
                },
                    this.prefabName
                    );
                insert(new List <VirtualGameObject> {
                    nextLineVGameObject
                });

                // return empty line.
                new ContentAndWidthAndHeight(string.Empty, 0, 0);
            }

            while (true)
            {
                // if rest text is included by one line, line collection is done.
                if (generator.lineCount == 1)
                {
                    lines.Add(nextText);
                    break;
                }

                // Debug.LogError("nextText:" + nextText + " generator.lines.Count:" + generator.lines.Count);

                // 複数行が出たので、continue,

                // 折り返しが発生したところから先のtextを取得し、その前までをコンテンツとしてセットする必要がある。
                var nextTextLineInfo = generator.lines[1];
                var startIndex       = nextTextLineInfo.startCharIdx;

                lines.Add(nextText.Substring(0, startIndex));

                nextText = nextText.Substring(startIndex);
                // ここから先の行は、今は見る必要がなくて、ターゲットを切り替えて再度実行する。

                textComponent.text = nextText;

                // populate again.
                generator.Invalidate();

                // ここで、幅は与えられている最大のものを使えるはず(親から伝わってくる時点で本来はすり減ったのが来てるはず)
                generator.Populate(textComponent.text, textComponent.GetGenerationSettings(new Vector2(contentWidth, contentHeight)));
                if (generator.lineCount == 0)
                {
                    throw new Exception("no line detected 2. nextText:" + nextText);
                }
            }

            textComponent.text = lines[0];
            var preferredWidth = textComponent.preferredWidth;

            // reset.
            textComponent.text = string.Empty;

            /*
             *      insert new line contents after this content.
             */
            if (1 < lines.Count)
            {
                var newContentTexts = lines.GetRange(1, lines.Count - 1);

                // foreach (var s in newContentTexts) {
                //  Debug.LogError("s:" + s);
                // }

                var newVGameObjects = newContentTexts.Select(
                    t => new VirtualGameObject(
                        this.tag,
                        this.depth,
                        new Dictionary <KV_KEY, string>()
                {
                    { KV_KEY._CONTENT, t }
                },
                        this.prefabName
                        )
                    ).ToList();
                insert(newVGameObjects);
            }

            // Debug.LogError("preferredWidth:" + preferredWidth);

            return(new ContentAndWidthAndHeight(lines[0], preferredWidth, generator.lines[0].height));
        }
Exemplo n.º 9
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.º 10
0
 public VirtualTransform(VirtualGameObject gameObject)
 {
     this.vGameObject = gameObject;
 }
Exemplo n.º 11
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);
        }