public void UpdateLocation(int x, int y, int height, CaretSetting mode) { if (IsFinal) { throw new InvalidOperationException("CaretPosition is already finalised"); } CaretLocation loc = new CaretLocation(x, y, height); switch (mode) { case CaretSetting.Absolute: primary = loc; secondary = null; break; case CaretSetting.Accurate: primary = loc; break; case CaretSetting.Fallback: secondary = loc; break; } }
public override void GetCaretPosition(IGraphics gr, int x, int y, SelectionPoint sp, ref CaretPositionInfo cpi) { // TODO: M: this is very innefficient since it is called for all text nodes during search if (!ContainsSelectionPoint(sp)) { cpi.UpdateLocation(x + Width, y, Height, CaretSetting.Fallback); return; } TextSelectionPoint tsp = (TextSelectionPoint)sp; CaretSetting mode = CaretSetting.Absolute; gr.PushFont(gr.GetFontHandle(style.FontDesc)); try { int n = tsp.Index - start; if (n < 0) { // position is not in visible part of the string, it's // in whitespace that has been trimmed. cpi.UseSecondary = true; return; } else if (tsp.Index == 0) { // caret can be put somewhere else if necessary // TODO: L: this is a bit simplistic - will be wrong if text nodes are // split and first node ends with space and ends a line (!) mode = CaretSetting.Accurate; } string text = Text; if (n > text.Length) { // TODO: L: not sure exactly when this happens n = text.Length; } text = ProcessText(text.Substring(0, n)); int w = gr.MeasureText(text).Width; cpi.UpdateLocation(x + w, y, Height, mode); } finally { gr.PopFont(); } }