Example #1
0
        private static List <ButtonPrimitive> syn(string printBuffer)
        {
            var printString = printBuffer;
            var ret         = new List <ButtonPrimitive>();

            if (printString.Length == 0)
            {
                goto nonButton;
            }
            List <string> strs = null;

            if (!printString.Contains("[") || !printString.Contains("]"))
            {
                goto nonButton;
            }
            strs = lex(new StringStream(printString));
            if (strs == null)
            {
                goto nonButton;
            }
            var  beforeButton = false; //最初のボタン("[1]"とか)より前にテキストがある
            var  afterButton  = false; //最後のボタン("[1]"とか)より後にテキストがある
            var  buttonCount  = 0;
            long inpL         = 0;

            for (var i = 0; i < strs.Count; i++)
            {
                if (strs[i].Length == 0)
                {
                    continue;
                }
                var c = strs[i][0];
                if (LexicalAnalyzer.IsWhiteSpace(c))
                {
//ただの空白
                }
                //数値以外はボタン化しない方向にした。
                //else if ((c == '[') && (!isSymbols(strArray[i])))
                else if (isButtonCore(strs[i], ref inpL))
                {
//[]で囲まれた文字列。選択肢の核となるかどうかはこの段階では判定しない。
                    buttonCount++;
                    afterButton = false;
                }
                else
                {
//選択肢の説明になるかもしれない文字列
                    afterButton = true;
                    if (buttonCount == 0)
                    {
                        beforeButton = true;
                    }
                }
            }
            if (buttonCount <= 1)
            {
                var button = new ButtonPrimitive();
                button.Str       = printBuffer;
                button.CanSelect = buttonCount >= 1;
                button.Input     = inpL;
                ret.Add(button);
                return(ret);
            }
            buttonCount = 0;
            var  alignmentRight = !beforeButton && afterButton;      //説明はボタンの右固定
            var  alignmentLeft  = beforeButton && !afterButton;      //説明はボタンの左固定
            var  alignmentEtc   = !alignmentRight && !alignmentLeft; //臨機応変に
            var  canSelect      = false;
            long input          = 0;

            var        state  = 0;
            var        buffer = new StringBuilder();
            VoidMethod reduce = delegate
            {
                if (buffer.Length == 0)
                {
                    return;
                }
                var button = new ButtonPrimitive();
                button.Str       = buffer.ToString();
                button.CanSelect = canSelect;
                button.Input     = input;
                ret.Add(button);
                buffer.Remove(0, buffer.Length);
                canSelect = false;
                input     = 0;
            };

            for (var i = 0; i < strs.Count; i++)
            {
                if (strs[i].Length == 0)
                {
                    continue;
                }
                var c = strs[i][0];
                if (LexicalAnalyzer.IsWhiteSpace(c))
                {
//ただの空白
                    if ((state & 3) == 3 && alignmentEtc && strs[i].Length >= 2)
                    {
//核と説明を含んだものが完成していればボタン生成。
                        //一文字以下のスペースはキニシナイ。キャラ購入画面対策
                        reduce();
                        buffer.Append(strs[i]);
                        state = 0;
                    }
                    else
                    {
                        buffer.Append(strs[i]);
                    }
                    continue;
                }
                if (isButtonCore(strs[i], ref inpL))
                {
                    buttonCount++;
                    if ((state & 1) == 1 || alignmentRight)
                    {
//bufferが既に核を含んでいる、又は強制的に右配置
                        reduce();
                        buffer.Append(strs[i]);
                        input     = inpL;
                        canSelect = true;
                        state     = 1;
                    } //((state & 2) == 2) ||
                    else if (alignmentLeft)
                    {
//bufferが説明を含んでいる、又は強制的に左配置
                        buffer.Append(strs[i]);
                        input     = inpL;
                        canSelect = true;
                        reduce();
                        state = 0;
                    }
                    else
                    {
//bufferが空または空白文字列
                        buffer.Append(strs[i]);
                        input     = inpL;
                        canSelect = true;
                        state     = 1;
                    }
                    continue;
                }
                //else
                //{//選択肢の説明になるかもしれない文字列

                buffer.Append(strs[i]);
                state |= 2;
                //}
            }
            ;
            reduce();
            return(ret);

nonButton:
            ret = new List <ButtonPrimitive>();
            var singleButton = new ButtonPrimitive();

            singleButton.Str = printString;
            ret.Add(singleButton);
            return(ret);
        }
Example #2
0
        /// <summary>
        /// 物理行をボタン単位に分割。引数のcssListの内容は変更される場合がある。
        /// </summary>
        /// <returns></returns>
        private ConsoleButtonString[] createButtons(List <AConsoleDisplayPart> cssList)
        {
            StringBuilder buf = new StringBuilder();

            for (int i = 0; i < cssList.Count; i++)
            {
                buf.Append(cssList[i].Str);
            }
            List <ButtonPrimitive> bpList = ButtonStringCreator.SplitButton(buf.ToString());

            ConsoleButtonString[] ret      = new ConsoleButtonString[bpList.Count];
            AConsoleDisplayPart[] cssArray = null;
            if (ret.Length == 1)
            {
                cssArray = new AConsoleDisplayPart[cssList.Count];
                cssList.CopyTo(cssArray);
                if (bpList[0].CanSelect)
                {
                    ret[0] = new ConsoleButtonString(parent, cssArray, bpList[0].Input);
                }
                else
                {
                    ret[0] = new ConsoleButtonString(parent, cssArray);
                }
                return(ret);
            }
            int cssStartCharIndex  = 0;
            int buttonEndCharIndex = 0;
            int cssIndex           = 0;
            List <AConsoleDisplayPart> buttonCssList = new List <AConsoleDisplayPart>();

            for (int i = 0; i < ret.Length; i++)
            {
                ButtonPrimitive bp = bpList[i];
                buttonEndCharIndex += bp.Str.Length;
                while (true)
                {
                    if (cssIndex >= cssList.Count)
                    {
                        break;
                    }
                    AConsoleDisplayPart css = cssList[cssIndex];
                    if (cssStartCharIndex + css.Str.Length >= buttonEndCharIndex)
                    {                    //ボタンの終端を発見
                        int used = buttonEndCharIndex - cssStartCharIndex;
                        if (used > 0 && css.CanDivide)
                        {                        //cssの区切りの途中でボタンの区切りがある。
                            ConsoleStyledString newCss = ((ConsoleStyledString)css).DivideAt(used);
                            if (newCss != null)
                            {
                                cssList.Insert(cssIndex + 1, newCss);
                                newCss.PointX = css.PointX + css.Width;
                            }
                        }
                        buttonCssList.Add(css);
                        cssStartCharIndex += css.Str.Length;
                        cssIndex++;
                        break;
                    }
                    //ボタンの終端はまだ先。
                    buttonCssList.Add(css);
                    cssStartCharIndex += css.Str.Length;
                    cssIndex++;
                }
                cssArray = new AConsoleDisplayPart[buttonCssList.Count];
                buttonCssList.CopyTo(cssArray);
                if (bp.CanSelect)
                {
                    ret[i] = new ConsoleButtonString(parent, cssArray, bp.Input);
                }
                else
                {
                    ret[i] = new ConsoleButtonString(parent, cssArray);
                }
                buttonCssList.Clear();
            }
            return(ret);
        }
        private static List<ButtonPrimitive> syn(string printBuffer)
        {
            string printString = printBuffer.ToString();
            List<ButtonPrimitive> ret = new List<ButtonPrimitive>();
            if (printString.Length == 0)
                goto nonButton;
            List<string> strs = null;
            if ((!printString.Contains("[")) || (!printString.Contains("]")))
                goto nonButton;
            strs = lex(new StringStream(printString));
            if (strs == null)
                goto nonButton;
            bool beforeButton = false;//最初のボタン("[1]"とか)より前にテキストがある
            bool afterButton = false;//最後のボタン("[1]"とか)より後にテキストがある
            int buttonCount = 0;
            Int64 inpL = 0;
            for (int i = 0; i < strs.Count; i++)
            {
                if (strs[i].Length == 0)
                    continue;
                char c = strs[i][0];
                if (LexicalAnalyzer.IsWhiteSpace(c))
                {//ただの空白
                }
                //数値以外はボタン化しない方向にした。
                //else if ((c == '[') && (!isSymbols(strArray[i])))
                else if (isButtonCore(strs[i], ref inpL))
                {//[]で囲まれた文字列。選択肢の核となるかどうかはこの段階では判定しない。
                    buttonCount++;
                    afterButton = false;
                }
                else
                {//選択肢の説明になるかもしれない文字列
                    afterButton = true;
                    if (buttonCount == 0)
                        beforeButton = true;
                }
            }
            if (buttonCount <= 1)
            {
                ButtonPrimitive button = new ButtonPrimitive();
                button.Str = printBuffer.ToString();
                button.CanSelect = (buttonCount >= 1);
                button.Input = inpL;
                ret.Add(button);
                return ret;
            }
            buttonCount = 0;
            bool alignmentRight = !beforeButton && afterButton;//説明はボタンの右固定
            bool alignmentLeft = beforeButton && !afterButton;//説明はボタンの左固定
            bool alignmentEtc = !alignmentRight && !alignmentLeft;//臨機応変に
            bool canSelect = false;
            Int64 input = 0;

            int state = 0;
            StringBuilder buffer = new StringBuilder();
            VoidMethod reduce = delegate
            {
                if (buffer.Length == 0)
                    return;
                ButtonPrimitive button = new ButtonPrimitive();
                button.Str = buffer.ToString();
                button.CanSelect = canSelect;
                button.Input = input;
                ret.Add(button);
                buffer.Remove(0, buffer.Length);
                canSelect = false;
                input = 0;
            };
            for (int i = 0; i < strs.Count; i++)
            {
                if (strs[i].Length == 0)
                    continue;
                char c = strs[i][0];
                if (LexicalAnalyzer.IsWhiteSpace(c))
                {//ただの空白
                    if (((state & 3) == 3) && (alignmentEtc) && (strs[i].Length >= 2))
                    {//核と説明を含んだものが完成していればボタン生成。
                        //一文字以下のスペースはキニシナイ。キャラ購入画面対策
                        reduce();
                        buffer.Append(strs[i]);
                        state = 0;
                    }
                    else
                    {
                        buffer.Append(strs[i]);
                    }
                    continue;
                }
                if(isButtonCore(strs[i], ref inpL))
                {
                    buttonCount++;
                    if (((state & 1) == 1) || alignmentRight)
                    {//bufferが既に核を含んでいる、又は強制的に右配置
                        reduce();
                        buffer.Append(strs[i]);
                        input = inpL;
                        canSelect = true;
                        state = 1;
                    }//((state & 2) == 2) ||
                    else if (alignmentLeft)
                    {//bufferが説明を含んでいる、又は強制的に左配置
                        buffer.Append(strs[i]);
                        input = inpL;
                        canSelect = true;
                        reduce();
                        state = 0;
                    }
                    else
                    {//bufferが空または空白文字列
                        buffer.Append(strs[i]);
                        input = inpL;
                        canSelect = true;
                        state = 1;
                    }
                    continue;
                }
                //else
                //{//選択肢の説明になるかもしれない文字列

                    buffer.Append(strs[i]);
                    state |= 2;
                //}

            };
            reduce();
            return ret;
            nonButton:
            ret = new List<ButtonPrimitive>();
            ButtonPrimitive singleButton = new ButtonPrimitive();
            singleButton.Str = printString;
            ret.Add(singleButton);
            return ret;
        }