public override void PrepareSelectionAnchor(SelectionAnchorCaret caret) { if (caret.Fragment == null) { Debug.Assert(Chunk.SequenceNumber == caret.Anchor?.Chunk.SequenceNumber); // find fragment at anchor offset var offset = caret.Anchor.Offset; int index = ViewContent.TextLayer.FindInRange(FirstFragmentIndex, LastFragmentIndex, f => ((TextFragment)f).Offset <= offset ? -1 : 1) - 1; caret.Fragment = ViewContent.TextLayer.Items[index]; } var fragment = caret.Fragment; var txtFrag = (TextFragment)fragment; var txtFragOffset = txtFrag.Offset; var txtFragLen = txtFrag.Length; var charWidth = fragment.View.Content.CharWidth; var fragLoc = fragment.Bounds.Location; var toTheEnd = false; if (caret.Anchor == null) { Debug.Assert(caret.Fragment?.IsSelectable == true); Debug.Assert(Chunk == caret.Fragment.Source.BaseChunk); caret.Anchor = new SelectionAnchor() { Chunk = Chunk }; if (fragment.View.Mouse.Position.Y > fragment.Bounds.Bottom) { caret.Anchor.Offset = fragment.IsTrailing ? txtFrag.Data.Length : txtFragLen + txtFragOffset; toTheEnd = true; } else { double pos = fragment.View.Mouse.Position.X + charWidth / 2.0; caret.Anchor.Offset = Math.Min(txtFragLen, Math.Max(0, (int)((pos - fragLoc.X) / charWidth))) + txtFragOffset; } } else { if (caret.Anchor.Offset >= Chunk.Payload.Length) { toTheEnd = true; } } caret.Bounds = new Rect( toTheEnd ? fragment.Bounds.Right : fragLoc.X + (caret.Anchor.Offset - txtFragOffset) * charWidth, fragLoc.Y, charWidth, fragment.Bounds.Height); }
/// <summary> /// Method should resolve missing properties <see cref="SelectionAnchorCaret.Fragment"/> or <see cref="SelectionAnchorCaret.Anchor"/> and update <see cref="SelectionAnchorCaret.Bounds"/>. /// </summary> public virtual void PrepareSelectionAnchor(SelectionAnchorCaret caret) => throw new NotImplementedException();