コード例 #1
0
ファイル: GLTextBox.cs プロジェクト: rainrcn/GLGUI
        private void RemoveSelection()
        {
            int first  = Math.Min(selectionStart.Index, cursorPosition.Index);
            int length = Math.Max(selectionStart.Index, cursorPosition.Index) - first;

            text = text.Remove(first, length);
            cursorPosition.Index = first;
            selectionStart       = cursorPosition;
        }
コード例 #2
0
ファイル: GLTextBox.cs プロジェクト: rainrcn/GLGUI
 private void OnMouseMove(object sender, MouseMoveEventArgs e)
 {
     if (isDragged)
     {
         cursorPosition.Index    = int.MaxValue;
         cursorPosition.Position = new Vector2(e.X - Inner.X, e.Y - Inner.Y);
         cursorPosition          = skin.Font.GetTextPosition(textProcessed, cursorPosition);
     }
 }
コード例 #3
0
ファイル: GLTextBox.cs プロジェクト: rainrcn/GLGUI
 private void OnMouseDown(object sender, MouseButtonEventArgs e)
 {
     if (enabled && e.Button == MouseButton.Left)
     {
         isDragged               = true;
         cursorPosition.Index    = int.MaxValue;
         cursorPosition.Position = new Vector2(e.X - Inner.X, e.Y - Inner.Y);
         cursorPosition          = skin.Font.GetTextPosition(textProcessed, cursorPosition);
         selectionStart          = cursorPosition;
     }
 }
コード例 #4
0
ファイル: GLTextBox.cs プロジェクト: rainrcn/GLGUI
        private void Insert(string str)
        {
            future.Clear();
            history.Push(text);

            if (selectionStart.Index != cursorPosition.Index)
            {
                RemoveSelection();
            }

            text = text.Insert(cursorPosition.Index, str);
            cursorPosition.Index += str.Length;
            selectionStart        = cursorPosition;
            Invalidate();
            if (Changed != null)
            {
                Changed(this, EventArgs.Empty);
            }
        }
コード例 #5
0
ファイル: GLTextBox.cs プロジェクト: rainrcn/GLGUI
        protected override void UpdateLayout()
        {
            skin = Enabled ? (HasFocus ? skinActive : (over ? skinHover : skinEnabled)) : skinDisabled;

            outer.Width = Math.Min(Math.Max(outer.Width, sizeMin.Width), sizeMax.Width);

            textSize = skin.Font.ProcessText(textProcessed, text,
                                             new SizeF(
                                                 WordWrap ?
                                                 (AutoSize ? float.MaxValue : outer.Width - skin.Border.Horizontal - skin.Padding.Horizontal)
                        : SizeMax.Width - skin.Border.Horizontal - skin.Padding.Horizontal,
                                                 Multiline ?
                                                 (AutoSize ? float.MaxValue : outer.Height - skin.Border.Vertical - skin.Padding.Vertical)
                        : skin.Font.LineSpacing),
                                             skin.TextAlign);
            int minHeight = Math.Max(sizeMin.Height, (int)textSize.Height + skin.Border.Vertical + skin.Padding.Vertical);

            if (AutoSize)
            {
                outer.Width  = (int)textSize.Width + skin.Border.Horizontal + skin.Padding.Horizontal;
                outer.Height = minHeight;
                outer.Width  = Math.Min(Math.Max(outer.Width, sizeMin.Width), sizeMax.Width);
            }

            outer.Height = Math.Min(Math.Max(Multiline ? outer.Height : (int)skin.Font.LineSpacing + skin.Border.Vertical + skin.Padding.Vertical, sizeMin.Height), sizeMax.Height);

            background = new Rectangle(
                skin.Border.Left, skin.Border.Top,
                outer.Width - skin.Border.Horizontal, outer.Height - skin.Border.Vertical);
            Inner = new Rectangle(
                background.Left + skin.Padding.Left, background.Top + skin.Padding.Top,
                background.Width - skin.Padding.Horizontal, background.Height - skin.Padding.Vertical);

            cursorPosition.Position = new Vector2(float.MaxValue, float.MaxValue);
            cursorPosition          = skin.Font.GetTextPosition(textProcessed, cursorPosition);
            selectionStart.Position = new Vector2(float.MaxValue, float.MaxValue);
            selectionStart          = skin.Font.GetTextPosition(textProcessed, selectionStart);
        }
コード例 #6
0
        private bool GetWordPosition(float x, float y, GLFontTextNode node, GLFontTextPosition position, ref int character, out Vector2 p)
        {
            bool sameLine = (long)(y / lineSpacingCache) == (long)(position.Position.Y / lineSpacingCache);

            if (node.Type == GLFontTextNodeType.Space || node.Type == GLFontTextNodeType.Tab)
            {
                p = new Vector2(x, y);
                if (position.Index == character || (sameLine && x + node.ModifiedLength * 0.5f > position.Position.X))
                {
                    return(true);
                }
                character++;
                return(false);
            }

            int  charGaps      = node.Text.Length - 1;
            bool isCrumbleWord = CrumbledWord(node);

            if (isCrumbleWord)
            {
                charGaps++;
            }

            int pixelsPerGap   = 0;
            int leftOverPixels = 0;

            if (charGaps != 0)
            {
                pixelsPerGap   = (int)node.LengthTweak / charGaps;
                leftOverPixels = (int)node.LengthTweak - pixelsPerGap * charGaps;
            }

            for (int i = 0; i < node.Text.Length; i++)
            {
                char c = node.Text[i];
                if (fontData.CharSetMapping.ContainsKey(c))
                {
                    var glyph = fontData.CharSetMapping[c];

                    float oldX = x;

                    if (isMonospacingActiveCache)
                    {
                        x += monoSpaceWidthCache;
                    }
                    else
                    {
                        x += (int)Math.Ceiling(glyph.Rect.Width + fontData.meanGlyphWidth * Options.CharacterSpacing + fontData.GetKerningPairCorrection(i, node.Text, node));
                    }

                    x += pixelsPerGap;
                    if (leftOverPixels > 0)
                    {
                        x += 1.0f;
                        leftOverPixels--;
                    }
                    else if (leftOverPixels < 0)
                    {
                        x -= 1.0f;
                        leftOverPixels++;
                    }

                    if (position.Index == character || (sameLine && (oldX + x) * 0.5f > position.Position.X))
                    {
                        p = new Vector2(oldX, y);
                        return(true);
                    }
                }
                character++;
            }
            p = new Vector2();
            return(false);
        }
コード例 #7
0
        public GLFontTextPosition GetTextPosition(GLFontText processedText, GLFontTextPosition position)
        {
            float maxMeasuredWidth = 0f;

            float xOffset = 0f;
            float yOffset = 0f;

            int character = 0;

            lineSpacingCache         = LineSpacing;
            isMonospacingActiveCache = IsMonospacingActive;
            monoSpaceWidthCache      = MonoSpaceWidth;
            float maxWidth  = processedText.maxSize.Width;
            var   alignment = processedText.alignment;
            var   nodeList  = processedText.textNodeList;

            for (GLFontTextNode node = nodeList.Head; node != null; node = node.Next)
            {
                node.LengthTweak = 0f;  //reset tweaks
            }
            if (alignment == GLFontAlignment.Right)
            {
                xOffset -= (float)Math.Ceiling(TextNodeLineLength(nodeList.Head, maxWidth) - maxWidth);
            }
            else if (alignment == GLFontAlignment.Centre)
            {
                xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(nodeList.Head, maxWidth));
            }
            else if (alignment == GLFontAlignment.Justify)
            {
                JustifyLine(nodeList.Head, maxWidth);
            }

            bool  atLeastOneNodeCosumedOnLine = false;
            float length = 0f;

            for (GLFontTextNode node = nodeList.Head; node != null; node = node.Next)
            {
                bool newLine = false;

                if (node.Type == GLFontTextNodeType.LineBreak)
                {
                    newLine = true;
                    if (character == position.Index)
                    {
                        return new GLFontTextPosition()
                               {
                                   Index = character, Position = new Vector2(xOffset + length, yOffset)
                               }
                    }
                    ;
                    character++;
                }
                else
                {
                    if (Options.WordWrap && SkipTrailingSpace(node, length, maxWidth) && atLeastOneNodeCosumedOnLine)
                    {
                        newLine = true;

                        if (character == position.Index)
                        {
                            return new GLFontTextPosition()
                                   {
                                       Index = character, Position = new Vector2(xOffset + length, yOffset)
                                   }
                        }
                        ;
                        character++;
                    }
                    else if (length + node.ModifiedLength <= maxWidth || !atLeastOneNodeCosumedOnLine)
                    {
                        atLeastOneNodeCosumedOnLine = true;

                        Vector2 p;
                        if (GetWordPosition(xOffset + length, yOffset, node, position, ref character, out p))
                        {
                            return new GLFontTextPosition()
                                   {
                                       Index = character, Position = p
                                   }
                        }
                        ;

                        length += node.ModifiedLength;

                        maxMeasuredWidth = Math.Max(length, maxMeasuredWidth);
                    }
                    else if (Options.WordWrap)
                    {
                        newLine = true;
                        if (node.Previous != null)
                        {
                            node = node.Previous;
                        }
                    }
                    else
                    {
                        continue; // continue so we still read line breaks even if reached max width
                    }
                }

                if (newLine)
                {
                    if (yOffset + lineSpacingCache >= processedText.maxSize.Height)
                    {
                        break;
                    }

                    if ((long)(yOffset / lineSpacingCache) == (long)(position.Position.Y / lineSpacingCache))
                    {
                        return new GLFontTextPosition()
                               {
                                   Index = character - 1, Position = new Vector2(xOffset + length, yOffset)
                               }
                    }
                    ;

                    yOffset += lineSpacingCache;
                    xOffset  = 0f;
                    length   = 0f;
                    atLeastOneNodeCosumedOnLine = false;

                    if (node.Next != null)
                    {
                        if (alignment == GLFontAlignment.Right)
                        {
                            xOffset -= (float)Math.Ceiling(TextNodeLineLength(node.Next, maxWidth) - maxWidth);
                        }
                        else if (alignment == GLFontAlignment.Centre)
                        {
                            xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(node.Next, maxWidth));
                        }
                        else if (alignment == GLFontAlignment.Justify)
                        {
                            JustifyLine(node.Next, maxWidth);
                        }
                    }
                }
            }

            return(new GLFontTextPosition()
            {
                Index = character, Position = new Vector2(xOffset + length, yOffset)
            });
        }
コード例 #8
0
ファイル: GLTextBox.cs プロジェクト: rainrcn/GLGUI
 private bool OnKeyDown(object sender, KeyboardKeyEventArgs e)
 {
     if (!enabled)
     {
         return(false);
     }
     if (e.Key == Key.Delete)
     {
         if (selectionStart.Index != cursorPosition.Index)
         {
             future.Clear();
             history.Push(text);
             RemoveSelection();
         }
         else if (cursorPosition.Index < text.Length)
         {
             future.Clear();
             history.Push(text);
             text = text.Remove(cursorPosition.Index, 1);
         }
         else
         {
             return(true);
         }
         Invalidate();
         if (Changed != null)
         {
             Changed(this, e);
         }
         return(true);
     }
     if (e.Key == Key.BackSpace)
     {
         if (selectionStart.Index != cursorPosition.Index)
         {
             future.Clear();
             history.Push(text);
             RemoveSelection();
         }
         else if (cursorPosition.Index > 0)
         {
             future.Clear();
             history.Push(text);
             text           = text.Remove(--cursorPosition.Index, 1);
             selectionStart = cursorPosition;
         }
         else
         {
             return(true);
         }
         Invalidate();
         if (Changed != null)
         {
             Changed(this, e);
         }
         return(true);
     }
     if (e.Key == Key.Enter && Multiline)
     {
         Insert("\n");
         return(true);
     }
     if (e.Key == Key.Left && cursorPosition.Index > 0)
     {
         cursorPosition.Index--;
         cursorPosition.Position = new Vector2(float.MaxValue, float.MaxValue);
         cursorPosition          = skin.Font.GetTextPosition(textProcessed, cursorPosition);
         if (!e.Shift)
         {
             selectionStart = cursorPosition;
         }
         return(true);
     }
     if (e.Key == Key.Right && cursorPosition.Index < text.Length)
     {
         cursorPosition.Index++;
         cursorPosition.Position = new Vector2(float.MaxValue, float.MaxValue);
         cursorPosition          = skin.Font.GetTextPosition(textProcessed, cursorPosition);
         if (!e.Shift)
         {
             selectionStart = cursorPosition;
         }
         return(true);
     }
     if (e.Key == Key.Up && cursorPosition.Position.Y > 0.0f)
     {
         cursorPosition.Index       = int.MaxValue;
         cursorPosition.Position.Y -= skin.Font.LineSpacing;
         cursorPosition             = skin.Font.GetTextPosition(textProcessed, cursorPosition);
         if (!e.Shift)
         {
             selectionStart = cursorPosition;
         }
         return(true);
     }
     if (e.Key == Key.Down)
     {
         cursorPosition.Index       = int.MaxValue;
         cursorPosition.Position.Y += skin.Font.LineSpacing;
         cursorPosition             = skin.Font.GetTextPosition(textProcessed, cursorPosition);
         if (!e.Shift)
         {
             selectionStart = cursorPosition;
         }
         return(true);
     }
     if (e.Control && e.Key == Key.A)
     {
         selectionStart.Index    = 0;
         selectionStart.Position = new Vector2(float.MaxValue, float.MaxValue);
         selectionStart          = skin.Font.GetTextPosition(textProcessed, selectionStart);
         cursorPosition.Index    = text.Length;
         cursorPosition.Position = new Vector2(float.MaxValue, float.MaxValue);
         cursorPosition          = skin.Font.GetTextPosition(textProcessed, cursorPosition);
         return(true);
     }
     if (e.Control && e.Key == Key.X)
     {
         if (selectionStart.Index != cursorPosition.Index)
         {
             future.Clear();
             history.Push(text);
             CopySelection();
             RemoveSelection();
             Invalidate();
             if (Changed != null)
             {
                 Changed(this, e);
             }
         }
         return(true);
     }
     if (e.Control && e.Key == Key.C)
     {
         if (selectionStart.Index != cursorPosition.Index)
         {
             CopySelection();
         }
         return(true);
     }
     if (e.Control && e.Key == Key.V)
     {
         if (Clipboard.ContainsText())
         {
             Insert(Clipboard.GetText());
         }
         return(true);
     }
     if (e.Control && e.Key == Key.Z)
     {
         if (!e.Shift)
         {
             if (history.Count > 0)
             {
                 future.Push(text);
                 text = history.Pop();
                 Invalidate();
             }
         }
         else if (future.Count > 0)
         {
             history.Push(text);
             text = future.Pop();
             Invalidate();
         }
         return(true);
     }
     if (e.Key == Key.Tab)
     {
         if (selectionStart.Index != cursorPosition.Index)
         {
             Indent(e.Shift);
         }
         else
         {
             Insert("\t");
         }
         return(true);
     }
     if (e.Key == Key.Home)
     {
         cursorPosition.Index      = int.MaxValue;
         cursorPosition.Position.X = 0;
         cursorPosition            = skin.Font.GetTextPosition(textProcessed, cursorPosition);
         if (!e.Shift)
         {
             selectionStart = cursorPosition;
         }
         return(true);
     }
     if (e.Key == Key.End)
     {
         cursorPosition.Index      = int.MaxValue;
         cursorPosition.Position.X = float.MaxValue;
         cursorPosition            = skin.Font.GetTextPosition(textProcessed, cursorPosition);
         if (!e.Shift)
         {
             selectionStart = cursorPosition;
         }
         return(true);
     }
     return(false);
 }