예제 #1
0
        /// <summary>
        /// When the text / scroll / highlight changes we need to
        /// re-compute how we are going to draw this text field
        /// </summary>
        public void ComputeDrawingCommands()
        {
            m_DrawCmds.Clear();
            m_DrawDirty = false;

            /**
             * Split the text into lines using manual lines
             * breaks and word wrap
             */
            string txt = null;

            if (m_Password)
            {
                /** Use * instead **/
                txt = "";
                for (int i = 0; i < m_SBuilder.Length; i++)
                {
                    txt += "*";
                }
            }
            else
            {
                txt = CurrentTextParsed;
            }

            var lineWidth = m_Width - (TextMargin.Left + TextMargin.Height);

            m_LineHeight = TextStyle.MeasureString("W").Y + TextStyle.LineHeightModifier;

            var bbCommands = BBCodeEnabled ? CodeParser.Commands : new List <BBCodeCommand>();
            var bbIndex    = 0;

            m_Lines.Clear();
            //txt = txt.Replace("\r", "");
            var words      = txt.Split(' ').ToList();
            var spaceWidth = TextStyle.MeasureString(" ").X;

            /**
             * Modify the array to make manual line breaks their own segment
             * in the array
             */
            var newWordsArray = TextRenderer.ExtractLineBreaks(words);

            TextRenderer.CalculateLines(m_Lines, newWordsArray, TextStyle, lineWidth, spaceWidth, new Vector2(), m_LineHeight);

            var topLeft  = new Vector2(TextMargin.Left, TextMargin.Top);
            var position = topLeft;
            var txtScale = TextStyle.Scale * _Scale;

            m_NumVisibleLines = Math.Max(1, (int)Math.Floor(m_Height / m_LineHeight));
            /** Make sure the current vscroll is valid **/
            VerticalScrollPosition = m_VScroll;

            if (m_Slider != null)
            {
                m_Slider.MaxValue = Math.Max(0, m_Lines.Count - m_NumVisibleLines);
                m_Slider.Value    = VerticalScrollPosition;
            }

            var bbColorStack = new Stack <Color>();
            var lastColor    = TextStyle.Color;

            var yPosition     = topLeft.Y;
            var numLinesAdded = 0;
            var shadowApplied = false;

            for (var i = 0; i < m_Lines.Count - m_VScroll; i++)
            {
                var line = m_Lines[m_VScroll + i];

                var segments  = CalculateSegments(line, bbCommands, ref bbIndex);
                var xPosition = topLeft.X;
                segments.ForEach(x => x.Size = TextStyle.MeasureString(x.Text));
                var thisLineWidth = segments.Sum(x => x.Size.X);

                /** Alignment **/
                if (Alignment == TextAlignment.Center)
                {
                    xPosition += (int)Math.Round((lineWidth - thisLineWidth) / 2);
                }
                line.LineStartX = (int)xPosition;

                foreach (var segment in segments)
                {
                    var segmentSize     = segment.Size;
                    var segmentPosition = LocalPoint(new Vector2(xPosition, yPosition));

                    if (segment.Selected)
                    {
                        m_DrawCmds.Add(new TextDrawCmd_SelectionBox
                        {
                            BlendColor = TextStyle.SelectionBoxColor,
                            Texture    = TextureGenerator.GetPxWhite(GameFacade.GraphicsDevice),
                            Position   = segmentPosition,
                            Scale      = new Vector2(segmentSize.X, m_LineHeight) * _Scale
                        });
                    }

                    if (segment.Text.Length > 0)
                    {
                        m_DrawCmds.Add(new TextDrawCmd_Text
                        {
                            Selected = segment.Selected,
                            Text     = segment.Text,
                            Style    = TextStyle,
                            Position = segmentPosition,
                            Scale    = txtScale
                        });
                        xPosition += segmentSize.X;
                    }

                    if (segment.StartCommand != null)
                    {
                        var cmd = segment.StartCommand;
                        switch (cmd.Type)
                        {
                        case BBCodeCommandType.color:
                            if (cmd.Close)
                            {
                                //pop a color off our stack
                                if (bbColorStack.Count > 0)
                                {
                                    lastColor = bbColorStack.Pop();
                                    m_DrawCmds.Add(new TextDrawCmd_Color(TextStyle, lastColor));
                                }
                            }
                            else
                            {
                                bbColorStack.Push(lastColor);
                                lastColor = cmd.ParseColor();
                                m_DrawCmds.Add(new TextDrawCmd_Color(TextStyle, lastColor));
                            }
                            break;

                        case BBCodeCommandType.s:
                            if (cmd.Close)
                            {
                                m_DrawCmds.Add(new TextDrawCmd_Shadow(TextStyle, false));
                                shadowApplied = false;
                            }
                            else
                            {
                                m_DrawCmds.Add(new TextDrawCmd_Shadow(TextStyle, true));
                                shadowApplied = true;
                            }
                            break;

                        case BBCodeCommandType.emoji:
                            if (segment.BBCatchup)
                            {
                                break;
                            }
                            m_DrawCmds.Add(new TextDrawCmd_Emoji(TextStyle, cmd.Parameter, LocalPoint(new Vector2(xPosition, yPosition)), _Scale));
                            break;
                        }
                    }
                }



                yPosition  += m_LineHeight;
                position.Y += m_LineHeight;

                numLinesAdded++;
                if (numLinesAdded >= m_NumVisibleLines)
                {
                    break;
                }
            }
            if (shadowApplied)
            {
                m_DrawCmds.Add(new TextDrawCmd_Shadow(TextStyle, false));
            }

            while (bbColorStack.Count > 0)
            {
                lastColor = bbColorStack.Pop();
                m_DrawCmds.Add(new TextDrawCmd_Color(TextStyle, lastColor));
            }

            /** No cursor in read only mode **/
            if (m_IsReadOnly)
            {
                m_DrawCmds.ForEach(x => x.Init());
                return;
            }

            var start      = Control_GetSelectionStart();
            var cursorLine = GetLineForIndex(start);

            if (cursorLine != null && cursorLine.LineNumber >= m_VScroll && cursorLine.LineNumber < m_VScroll + m_NumVisibleLines)
            {
                var prefix         = start - cursorLine.StartIndex;
                var cursorPosition = new Vector2(cursorLine.LineStartX, topLeft.Y + ((cursorLine.LineNumber - m_VScroll) * m_LineHeight));

                if (prefix > 0)
                {
                    if (prefix > cursorLine.Text.Length - 1)
                    {
                        cursorPosition.X += cursorLine.LineWidth;
                    }
                    else
                    {
                        cursorPosition.X += TextStyle.MeasureString(cursorLine.Text.Substring(0, prefix)).X;
                    }
                }


                m_DrawCmds.Add(new TextDrawCmd_Cursor
                {
                    Scale    = new Vector2(_Scale.X, m_LineHeight * _Scale.Y),
                    Position = LocalPoint(cursorPosition),
                    Texture  = TextureGenerator.GetPxWhite(GameFacade.GraphicsDevice),
                    Color    = TextStyle.CursorColor
                });
            }

            m_DrawCmds.ForEach(x => x.Init());
        }
예제 #2
0
        /// <summary>
        /// When the text / scroll / highlight changes we need to
        /// re-compute how we are going to draw this text field
        /// </summary>
        public void ComputeDrawingCommands()
        {
            m_DrawCmds.Clear();
            m_DrawDirty = false;

            /**
             * Split the text into lines using manual lines
             * breaks and word wrap
             */
            var txt       = m_SBuilder.ToString();
            var lineWidth = m_Width - (TextMargin.Left + TextMargin.Height);

            m_LineHeight = TextStyle.MeasureString("W").Y;

            m_Lines.Clear();

            var words      = txt.Split(' ').ToList();
            var spaceWidth = TextStyle.MeasureString(" ").X;

            /**
             * Modify the array to make manual line breaks their own segment
             * in the array
             */
            var newWordsArray = TextRenderer.ExtractLineBreaks(words);

            TextRenderer.CalculateLines(m_Lines, newWordsArray, TextStyle, lineWidth, spaceWidth, new Vector2(), m_LineHeight);

            var topLeft  = new Vector2(TextMargin.Left, TextMargin.Top);
            var position = topLeft;
            var txtScale = TextStyle.Scale * _Scale;

            m_NumVisibleLines = (int)Math.Floor(m_Height / m_LineHeight);
            /** Make sure the current vscroll is valid **/
            VerticalScrollPosition = m_VScroll;

            if (m_Slider != null)
            {
                m_Slider.MaxValue = Math.Max(0, m_Lines.Count - m_NumVisibleLines);
                m_Slider.Value    = VerticalScrollPosition;
            }

            var yPosition     = topLeft.Y;
            var numLinesAdded = 0;

            for (var i = 0; i < m_Lines.Count - m_VScroll; i++)
            {
                var line = m_Lines[m_VScroll + i];

                var segments  = CalculateSegments(line);
                var xPosition = topLeft.X;
                segments.ForEach(x => x.Size = TextStyle.MeasureString(x.Text));
                var thisLineWidth = segments.Sum(x => x.Size.X);

                /** Alignment **/
                if (Alignment == TextAlignment.Center)
                {
                    xPosition += (int)Math.Round((lineWidth - thisLineWidth) / 2);
                }
                line.LineStartX = (int)xPosition;

                foreach (var segment in segments)
                {
                    var segmentSize     = segment.Size;
                    var segmentPosition = LocalPoint(new Vector2(xPosition, yPosition));

                    if (segment.Selected)
                    {
                        m_DrawCmds.Add(new TextDrawCmd_SelectionBox
                        {
                            BlendColor = new Color(0xFF, 0xFF, 0xFF, 200),
                            Texture    = TextureUtils.TextureFromColor(GameFacade.GraphicsDevice, TextStyle.SelectionBoxColor),
                            Position   = segmentPosition,
                            Scale      = new Vector2(segmentSize.X, m_LineHeight) * _Scale
                        });
                    }

                    m_DrawCmds.Add(new TextDrawCmd_Text
                    {
                        Selected = segment.Selected,
                        Text     = segment.Text,
                        Style    = TextStyle,
                        Position = segmentPosition,
                        Scale    = txtScale
                    });
                    xPosition += segmentSize.X;
                }

                yPosition  += m_LineHeight;
                position.Y += m_LineHeight;

                numLinesAdded++;
                if (numLinesAdded >= m_NumVisibleLines)
                {
                    break;
                }
            }

            /** No cursor in read only mode **/
            if (m_IsReadOnly)
            {
                m_DrawCmds.ForEach(x => x.Init());
                return;
            }

            var start      = Control_GetSelectionStart();
            var cursorLine = GetLineForIndex(start);

            if (cursorLine != null && cursorLine.LineNumber >= m_VScroll && cursorLine.LineNumber < m_VScroll + m_NumVisibleLines)
            {
                var prefix         = start - cursorLine.StartIndex;
                var cursorPosition = new Vector2(cursorLine.LineStartX, topLeft.Y + ((cursorLine.LineNumber - m_VScroll) * m_LineHeight));

                if (prefix > 0)
                {
                    if (prefix > cursorLine.Text.Length - 1)
                    {
                        cursorPosition.X += cursorLine.LineWidth;
                    }
                    else
                    {
                        cursorPosition.X += TextStyle.MeasureString(cursorLine.Text.Substring(0, prefix)).X;
                    }
                }

                m_DrawCmds.Add(new TextDrawCmd_Cursor
                {
                    Scale    = new Vector2(_Scale.X, m_LineHeight * _Scale.Y),
                    Position = LocalPoint(cursorPosition),
                    Texture  = TextureUtils.TextureFromColor(GameFacade.GraphicsDevice, TextStyle.CursorColor)
                });
            }

            m_DrawCmds.ForEach(x => x.Init());
        }