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; }
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); } }
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; } }
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); } }
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); }
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); }
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) }); }
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); }