/// <summary> /// Sets the focus to the visible cell view corresponding to a location. /// </summary> /// <param name="x">X-coordinate of the location where to set the focus.</param> /// <param name="y">Y-coordinate of the location where to set the focus.</param> /// <param name="resetAnchor">If true, resets the selected text anchor.</param> /// <param name="isMoved">True if the focus was moved.</param> public virtual void SetFocusToPoint(double x, double y, bool resetAnchor, out bool isMoved) { isMoved = false; ulong OldFocusHash = FocusHash; int OldIndex = FocusChain.IndexOf(Focus); int NewIndex = -1; // Takes page margins and padding into account. DrawContext.ToRelativeLocation(ref x, ref y); for (int i = 0; i < FocusChain.Count; i++) { ILayoutFocus TestFocus = (ILayoutFocus)FocusChain[i]; if (TestFocus.CellView.CellRect.IsPointInRect(x, y)) { NewIndex = i; break; } } if (NewIndex >= 0) { if (NewIndex != OldIndex) { ChangeFocus(NewIndex - OldIndex, OldIndex, NewIndex, resetAnchor, out bool IsRefreshed); } if (Focus is ILayoutTextFocus AsTextFocus) { Point CellOrigin = Focus.CellView.CellOrigin; Size CellSize = Focus.CellView.CellSize; double XRelativeToCell = x - CellOrigin.X.Draw; double YRelativeToCell = y - CellOrigin.Y.Draw; Debug.Assert(XRelativeToCell >= 0 && XRelativeToCell < CellSize.Width.Draw); Debug.Assert(YRelativeToCell >= 0 && YRelativeToCell < CellSize.Height.Draw); string Text = GetFocusedText(AsTextFocus); int NewCaretPosition = DrawContext.GetCaretPositionInText(XRelativeToCell, Text, FocusedTextStyle, CaretMode, Measure.Floating); Debug.Assert(NewCaretPosition >= 0 && NewCaretPosition <= MaxCaretPosition); SetTextCaretPosition(Text, NewCaretPosition, resetAnchor, out isMoved); } isMoved = true; } Debug.Assert(isMoved || OldFocusHash == FocusHash); }
private protected override void ChangeFocus(int direction, int oldIndex, int newIndex, bool resetAnchor, out bool isRefreshed) { ILayoutFocus OldFocus = (ILayoutFocus)FocusChain[oldIndex]; Debug.Assert(OldFocus == Focus); base.ChangeFocus(direction, oldIndex, newIndex, resetAnchor, out isRefreshed); ILayoutFocus NewFocus = Focus; Debug.Assert(NewFocus != OldFocus); if (OldFocus is ILayoutCommentFocus || NewFocus is ILayoutCommentFocus) { Invalidate(); } }
private void FindClosestFocusVertical(double distance, int oldFocusIndex, ref int newFocusIndex, ref double bestVerticalDistance, ref double bestHorizontalDistance) { Point Origin = GetMoveFocusDestinationLocation(distance); for (int i = 0; i < FocusChain.Count; i++) { int CellIndex = distance < 0 ? i : FocusChain.Count - i - 1; ILayoutFocus TestFocus = (ILayoutFocus)FocusChain[CellIndex]; ILayoutFocusableCellView CellView = TestFocus.CellView; // If we check against the current focus, it might be the closest cell and then we don't move! if (CellIndex == oldFocusIndex) { continue; } // Don't consider cells that are in the wrong direction; if ((distance < 0 && CellView.CellOrigin.Y.Draw >= Origin.Y.Draw) || (distance > 0 && CellView.CellOrigin.Y.Draw + CellView.CellSize.Height.Draw <= Origin.Y.Draw)) { continue; } if (CellView.CellRect.IsPointInRect(Origin.X.Draw, Origin.Y.Draw)) { newFocusIndex = CellIndex; break; } else { Point Center = CellView.CellRect.Center; double VerticalDistance = Math.Abs((Center.Y - Origin.Y).Draw); double HorizontalDistance = Math.Abs((Center.X - Origin.X).Draw); if (newFocusIndex < 0 || bestVerticalDistance > VerticalDistance || (RegionHelper.IsZero(bestVerticalDistance - VerticalDistance) && bestHorizontalDistance > HorizontalDistance)) { bestVerticalDistance = VerticalDistance; bestHorizontalDistance = HorizontalDistance; newFocusIndex = CellIndex; } } } }
private void FindClosestFocusHorizontal(int direction, ref int newFocusIndex, ref double bestSquaredDistance) { Point FocusCellOrigin = Focus.CellView.CellOrigin; Size FocusCellSize = Focus.CellView.CellSize; Point FocusCellCenter = Focus.CellView.CellRect.Center; for (int i = 0; i < FocusChain.Count; i++) { int CellIndex = direction < 0 ? i : FocusChain.Count - i - 1; ILayoutFocus TestFocus = (ILayoutFocus)FocusChain[CellIndex]; ILayoutFocusableCellView TestCellView = TestFocus.CellView; Point TestCellOrigin = TestCellView.CellOrigin; Size TestCellSize = TestCellView.CellSize; Point TestCellCenter = TestCellView.CellRect.Center; // Don't consider cells that are not on the same line; if ((TestCellOrigin.Y.Draw + TestCellSize.Height.Draw <= FocusCellOrigin.Y.Draw) || (TestCellOrigin.Y.Draw >= FocusCellOrigin.Y.Draw + FocusCellSize.Height.Draw)) { continue; } // Don't consider cells that are in the wrong direction; if ((direction < 0 && TestCellOrigin.X.Draw >= FocusCellOrigin.X.Draw + FocusCellSize.Width.Draw) || (direction >= 0 && TestCellOrigin.X.Draw + TestCellSize.Width.Draw <= FocusCellOrigin.X.Draw)) { continue; } double SquaredDistance = Point.SquaredDistance(FocusCellCenter, TestCellCenter); if (newFocusIndex < 0 || bestSquaredDistance < SquaredDistance) { bestSquaredDistance = SquaredDistance; newFocusIndex = CellIndex; } } }