private void UpdateTextLayout(IDraw sendMe = null) { float roX = 0, roY = 0; Object passageLocker = new Object(); lock (passageLocker) { if (sendMe == null) { textLayoutNeedsUpdate = true; Dirty(DisplayRectangle); return; } else { textLayoutNeedsUpdate = false; } // sort out some settings data.wrapped = layout == LayoutStyle.WrappedMultiLine; data.width = PaddedRectangle.width; data.height = PaddedRectangle.height; data.valign = (layout == LayoutStyle.OneLine) ? UVAlign.Middle : UVAlign.Top; bool rev = caretPos > shiftOrigin; selectRange.start = rev ? shiftOrigin : caretPos; selectRange.length = Math.Abs(caretPos - shiftOrigin); // get size of the render var ti = lastTextInfo = sendMe.uDraw.GetTextInfo(data); int lines = ti.numLines; Size tms = ti.minSize; float lineHeight = tms.height / (float)lines; // Get Caret location Point cp = sendMe.uDraw.HitText(caretPos, false, data); // determine render offset roX = cp.X > PaddedRectangle.width ? cp.X - PaddedRectangle.width : 0; roY = cp.Y > PaddedRectangle.height - lineHeight ? cp.Y - PaddedRectangle.height + lineHeight : 0; float yCenteringOffset = PaddedRectangle.height / 2 - lineHeight / 2; if (layout == LayoutStyle.OneLine) { roY += yCenteringOffset; } // set caret line caret1 = new Point((float)Math.Round(PaddedRectangle.left + cp.X - roX) + 0.5f, (float)Math.Round(PaddedRectangle.top + cp.Y - roY)); caret2 = new Point((float)Math.Round(PaddedRectangle.left + cp.X - roX) + 0.5f, (float)Math.Round(PaddedRectangle.top + cp.Y - roY + lineHeight)); } }
bool WrappedEndLine(UTextInfo ti, int lineNum) { if (ti.lineNewLineLength[lineNum] == 0) { // could be last line, could be wrapped if (ti.numLines == (lineNum + 1)) { return(false); } else { return(true); } } return(false); }
public UTextInfo NewTextInfo(TextLayout textLayout) { UTextInfo ret = new UTextInfo(); // get size of the render float minHeight = 0; ret.numLines = 0; ret.lineLengths = new int[textLayout.Metrics.LineCount]; ret.lineNewLineLength = new int[textLayout.Metrics.LineCount]; int i = 0; foreach (var tlm in textLayout.GetLineMetrics()) { minHeight += tlm.Height; ret.numLines++; ret.lineLengths[i] = tlm.Length; ret.lineNewLineLength[i] = tlm.NewlineLength; i++; } ret.minSize = new Size(textLayout.DetermineMinWidth(), minHeight); return(ret); }
public void KeyDown(Keys key) { if (!focusManager.FocusGet(this)) { return; } MKeys(key, true); if (alt) { return; } // We dont like \r\n or \r in our text! data.text = text.Replace("\r\n", "\n").Replace("\r", "\n"); // Copy if (ctrl && key == Keys.C) { String cs = BoundSubString(data.text, caretPos, shiftOrigin); if (cs != "") { SetClip(cs); } } // Cut if (ctrl && key == Keys.X) { String cs = BoundSubString(data.text, caretPos, shiftOrigin); if (cs != "") { SetClip(cs); } ReplaceSelectionWithText(""); } // Paste if (ctrl && key == Keys.V) { ReplaceSelectionWithText(GetClip()); } // Selcet all if (ctrl && key == Keys.A) { caretPos = data.text.Length; shiftOrigin = 0; } // Backspace if (key == Keys.Back && caretPos > 0) { if (caretPos != shiftOrigin) { ReplaceSelectionWithText(""); } else { data.text = data.text.Substring(0, caretPos - 1) + data.text.Substring(caretPos); caretPos--; } } if (shift && caretPos == shiftOrigin) { // cut line if (key == Keys.Delete) { int start, end; GetLineRange(out start, out end); String cs = BoundSubString(data.text, start, end); if (cs != "") { SetClip(cs); } data.text = data.text.Substring(0, start) + data.text.Substring(end, data.text.Length - end); caretPos = shiftOrigin = start; } // paste line if (key == Keys.Insert) { int lineNum, linePos; UTextInfo ti = lastTextInfo; FindMyLine(caretPos, ti.lineLengths, out lineNum, out linePos); _caretPos = shiftOrigin = caretPos - linePos; ReplaceSelectionWithText(GetClip().TrimEnd('\r', '\n') + "\n"); } } // Delete else if (key == Keys.Delete && caretPos < data.text.Length && !ctrl) { if (caretPos != shiftOrigin) { ReplaceSelectionWithText(""); } else { data.text = data.text.Substring(0, caretPos) + data.text.Substring(caretPos + 1); } } if (key == Keys.Left && caretPos > 0) { if (ctrl) { String lText = data.text.Substring(0, caretPos).Replace("\r", "\n").Replace("\n", " "); var reg = new Regex(@"\s+"); var mt = reg.Matches(lText); int cp = 0; if (mt.Count > 0) { cp = mt[mt.Count - 1].Index + mt[mt.Count - 1].Length; } if (cp == caretPos) { if (mt.Count > 1) { cp = caretPos = mt[mt.Count - 2].Index + mt[mt.Count - 2].Length; } else { cp = 0; } } caretPos = cp; } else { caretPos--; } } if (key == Keys.Right && caretPos < data.text.Length) { if (ctrl) { String rText = data.text.Substring(caretPos, data.text.Length - caretPos).Replace("\r", "\n").Replace("\n", " "); var reg = new Regex(@"\s+"); var mt = reg.Matches(rText); int cp = 0; if (mt.Count > 0) { cp = mt[0].Index + mt[0].Length; } else { cp = rText.Length; } caretPos += cp; } else { caretPos++; } } if (key == Keys.Up) { if (ctrl) { String lText = data.text.Substring(0, caretPos); var reg = new Regex("[^\n]\n\n+[^\n]", RegexOptions.Multiline); var mt = reg.Matches(lText); int cp = 0; if (mt.Count > 0) { cp = mt[mt.Count - 1].Index + mt[mt.Count - 1].Length - 1; } if (cp == caretPos) { if (mt.Count > 1) { cp = mt[mt.Count - 2].Index + mt[mt.Count - 2].Length; } else { cp = 0; } } caretPos = cp; } else { int lineNum, linePos; UTextInfo ti = lastTextInfo; FindMyLine(caretPos, ti.lineLengths, out lineNum, out linePos); if (lineNum != 0) // cant go up there! { int prevLine = 0; for (int i = 0; i < lineNum - 1; i++) { prevLine += ti.lineLengths[i]; } int prevLineLen = ti.lineLengths[lineNum - 1] - ti.lineNewLineLength[lineNum - 1]; if (linePos > prevLineLen) { linePos = prevLineLen; } caretPos = prevLine + linePos; } } } if (key == Keys.Down) { if (ctrl) { String rText = data.text.Substring(caretPos, data.text.Length - caretPos); var reg = new Regex("[^\n]\n\n+[^\n]", RegexOptions.Multiline); var mt = reg.Matches(rText); int cp = 0; if (mt.Count > 0) { cp = mt[0].Index + mt[0].Length - 1; } else { cp = rText.Length; } caretPos += cp; } else { int lineNum, linePos; UTextInfo ti = lastTextInfo; FindMyLine(caretPos, ti.lineLengths, out lineNum, out linePos); if (lineNum != ti.numLines - 1) // cant go down there! { int nextLine = 0; for (int i = 0; i < lineNum + 1; i++) { nextLine += ti.lineLengths[i]; } int nextLineLen = ti.lineLengths[lineNum + 1] - ti.lineNewLineLength[lineNum + 1]; if (linePos > nextLineLen) { linePos = nextLineLen; } caretPos = nextLine + linePos; } } } if (key == Keys.End) { if (ctrl) { caretPos = data.text.Length; } else { int lineNum, linePos; UTextInfo ti = lastTextInfo; FindMyLine(caretPos, ti.lineLengths, out lineNum, out linePos); int cp = caretPos + ti.lineLengths[lineNum] - linePos - 1; char c; while ((c = data.text[cp]) == '\r' || c == '\n') { cp--; } int el = WrappedEndLine(ti, lineNum) ? 0 : 1; caretPos = cp + el; } } if (key == Keys.Home) { if (ctrl) { caretPos = 0; } else { int lineNum, linePos; UTextInfo ti = lastTextInfo; FindMyLine(caretPos, ti.lineLengths, out lineNum, out linePos); caretPos -= linePos; } } }