Helper to TextControl component
Exemplo n.º 1
0
        /// <summary>
        /// Updates the size.
        /// </summary>
        private void UpdateSize()
        {
            if (!this.isInitialized)
            {
                return;
            }

            this.LinesInfo.Clear();

            if (!string.IsNullOrEmpty(this.text) && this.SpriteFont != null)
            {
                this.FontHeight = this.SpriteFont.MeasureString("A").Y;

                if (!this.RichTextEnabled)
                {
                    if (this.textWrapping)
                    {
                        // Filters
                        this.text = this.text.Replace("\r\n", " /n ");
                        this.text = this.text.Replace("\n", " /n ");
                        this.text = this.text.Replace("/n", " /n ");

                        string[] words = this.text.Split(' ');
                        var stringBuilder = new StringBuilder();

                        int i = 0;
                        while (i < words.Length)
                        {
                            do
                            {
                                if (words[i].Equals("/n"))
                                {
                                    i++;
                                    break;
                                }

                                string nextString = string.Format("{0}{1} ", stringBuilder, words[i]);
                                float lineSize = this.SpriteFont.MeasureString(nextString).X;
                                if (stringBuilder.Length != 0 && lineSize > this.Width)
                                {
                                    break;
                                }

                                stringBuilder.Append(words[i]);
                                stringBuilder.Append(" ");
                                i++;
                            }
                            while (i < words.Length);

                            string text = stringBuilder.ToString();
                            Vector2 size = this.SpriteFont.MeasureString(text);
                            float offsetX = this.CalculateAlignmentOffset(size);
                            this.LinesInfo.Add(new LineInfo(text, this.Foreground, size, offsetX));
                            stringBuilder.Length = 0;
                        }

                        this.Height = this.LinesInfo.Count * (this.FontHeight + this.lineSpacing);
                    }
                    else
                    {
                        Vector2 size = this.SpriteFont.MeasureString(this.text);
                        float offsetX = this.CalculateAlignmentOffset(size);
                        this.LinesInfo.Add(new LineInfo(this.text, this.Foreground, size, offsetX));

                        if (this.lineWidth != -1)
                        {
                            base.Width = this.lineWidth;
                        }
                        else
                        {
                            base.Width = size.X;
                        }

                        this.Height = size.Y;
                    }
                }
                else
                {
                    if (this.textWrapping)
                    {
                        // Filters
                        this.text = this.text.Replace("\r\n", " /n ");
                        this.text = this.text.Replace("\n", " /n ");
                        this.text = this.text.Replace("/n", " /n ");
                    }
                    else
                    {
                        base.Width = 0;
                    }

                    XDocument document = XDocument.Parse("<p>" + this.text + "</p>");

                    float acumulatedSize = 0;
                    int lineInfoId = 0;
                    this.LinesInfo.Add(new LineInfo(0));

                    XNode child = document.Root.FirstNode;
                    while (child != null)
                    {
                        Vector2 size;
                        Color color;
                        string textValue;

                        switch (child.NodeType)
                        {
                            case XmlNodeType.Element:
                                XElement element = child as XElement;
                                if (element.Name == "rtf" && element.Attribute("Foreground") != null)
                                {
                                    // Sets foreground 
                                    var colorAttribute = element.Attribute("Foreground");
                                    color = new Color(colorAttribute.Value);
                                }
                                else
                                {
                                    color = this.Foreground;
                                }

                                textValue = element.Value;
                                break;

                            case XmlNodeType.Text:
                                color = this.Foreground;
                                XText xText = child as XText;
                                textValue = xText.Value;
                                break;

                            default:
                                color = this.Foreground;
                                textValue = string.Empty;
                                break;
                        }

                        string[] textFragments;

                        if (!this.textWrapping)
                        {
                            textFragments = textValue.Split('\n');
                        }
                        else
                        {
                            textFragments = textValue.Split(' ');
                        }

                        var stringBuilder = new StringBuilder();

                        int i = 0;
                        while (i < textFragments.Length)
                        {
                            if (this.textWrapping)
                            {
                                stringBuilder.Clear();
                                do
                                {
                                    if (textFragments[i].Equals("/n"))
                                    {
                                        i++;
                                        break;
                                    }

                                    string currentFragment = textFragments[i].Trim();

                                    if (currentFragment == string.Empty)
                                    {
                                        i++;
                                        continue;
                                    }

                                    string nextString = string.Format("{0}{1} ", stringBuilder, currentFragment);
                                    float lineSize = this.SpriteFont.MeasureString(nextString).X + acumulatedSize;
                                    if (stringBuilder.Length != 0 && lineSize > this.Width)
                                    {
                                        break;
                                    }

                                    stringBuilder.Append(currentFragment);
                                    i++;

                                    stringBuilder.Append(" ");
                                }
                                while (i < textFragments.Length);
                            }
                            else
                            {
                                stringBuilder.Clear();
                                stringBuilder.Append(textFragments[i]);
                                i++;
                            }

                            size = this.SpriteFont.MeasureString(stringBuilder.ToString());

                            LineInfo lineInfo = this.LinesInfo[lineInfoId];
                            lineInfo.AddText(stringBuilder.ToString(), color, size);
                            this.LinesInfo[lineInfoId] = lineInfo;

                            acumulatedSize += size.X;

                            if (!this.textWrapping)
                            {
                                base.Width = MathHelper.Max(acumulatedSize, this.Width);
                            }

                            if (textFragments.Length > 1 && i < textFragments.Length)
                            {
                                this.LinesInfo.Add(new LineInfo(0));
                                lineInfoId++;

                                acumulatedSize = 0;
                            }
                        }

                        child = child.NextNode;
                    }

                    ////Debug.WriteLine("{");
                    float height = 0;
                    for (int i = 0; i < this.LinesInfo.Count; i++)
                    {
                        LineInfo info = this.LinesInfo[i];
                        info.AlignmentOffsetX = this.CalculateAlignmentOffset(info.Size);
                        this.LinesInfo[i] = info;

                        height += info.Size.Y;

                        ////Debug.WriteLine(string.Format("\tLineInfo [Size: {0} Offset: {1}]", info.Size, info.AlignmentOffsetX));

                        ////foreach (var fragment in info.SubTextList)
                        ////{
                        ////    Debug.WriteLine(string.Format("\t\tFragment [Size: {0} Text: \"{1}\"]", fragment.Size, fragment.Text));
                        ////}
                    }

                    ////Debug.WriteLine("}");

                    this.Height = height + (this.LineSpacing * this.LinesInfo.Count);

                    if (this.Owner != null && this.Owner.Parent != null)
                    {
                        this.Arrange(this.Owner.Parent.FindComponent<Transform2D>().Rectangle);
                    }
                }
                
                // Event
                if (this.OnWidthChanged != null)
                {
                    this.OnWidthChanged(this, this.Width);
                }
            }           
        }
Exemplo n.º 2
0
        /// <summary>
        /// Handles the TouchPressed event of the Gestures control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="GestureEventArgs" /> instance containing the event data.</param>
        private void Gestures_TouchPressed(object sender, GestureEventArgs e)
        {
            this.IsFocus = true;

            if (this.isReadOnly)
            {
                return;
            }

            if (this.inputService.KeyboardState.IsConnected)
            {
                float clickX = e.GestureSample.Position.X - this.Transform.Rectangle.X;
                float clickY = e.GestureSample.Position.Y - this.Transform.Rectangle.Y;

                // Cursor position Y
                float posY      = this.textControl.LineSpacing;
                int   lineIndex = 0;
                while (lineIndex < this.textControl.LinesInfo.Count - 1 &&
                       posY + this.textControl.FontHeight < clickY)
                {
                    posY += this.textControl.FontHeight + this.textControl.LineSpacing;
                    lineIndex++;
                }

                // Cursor position X
                float posX = 0;
                if (this.textControl.LinesInfo.Count > 0)
                {
                    LineInfo lineInfo = this.textControl.LinesInfo[lineIndex];
                    if (posY + this.textControl.FontHeight < clickY)
                    {
                        // Outside of textControl
                        posX = lineInfo.AlignmentOffsetX + lineInfo.Size.X;
                        this.textBeforeCursor = this.textControl.Text;
                        this.textAfterCursor  = string.Empty;
                    }
                    else
                    {
                        // Search X position
                        posX = lineInfo.AlignmentOffsetX;
                        float  maxOffsetX      = lineInfo.AlignmentOffsetX + lineInfo.Size.X;
                        int    characterIndex  = 0;
                        string currentLineText = lineInfo.SubTextList[0].Text;
                        float  characterOffset = this.textControl.SpriteFont.MeasureString(currentLineText[characterIndex].ToString()).X;
                        while (posX <= maxOffsetX &&
                               posX + (characterOffset / 2) < clickX)
                        {
                            posX += characterOffset;
                            if (characterIndex < currentLineText.Length - 1)
                            {
                                characterIndex++;
                                characterOffset = this.textControl.SpriteFont.MeasureString(currentLineText[characterIndex].ToString()).X;
                            }
                            else
                            {
                                break;
                            }
                        }

                        // Text before cursor
                        List <LineInfo> linesInfo = this.textControl.LinesInfo;
                        this.textBeforeCursor = string.Empty;
                        for (int i = 0; i < lineIndex; i++)
                        {
                            this.textBeforeCursor += this.textControl.LinesInfo[i].SubTextList[0].Text;
                        }

                        this.textBeforeCursor += currentLineText.Substring(0, characterIndex);

                        // Text After cursor
                        this.textAfterCursor = currentLineText.Substring(characterIndex);
                        for (int i = lineIndex + 1; i < this.textControl.LinesInfo.Count; i++)
                        {
                            this.textAfterCursor += this.textControl.LinesInfo[i].SubTextList[0].Text;
                        }
                    }
                }

                // Final positions
                this.cursorTransform.X = posX;
                this.cursorTransform.Y = posY;
                this.cursorAnimation.BeginAnimation(Transform2D.OpacityProperty, this.flicker);
            }
            else
            {
                this.ShowScreenKeyboard();
            }
        }