/// <inheritdoc/> protected override void OnManipulationCompleted(ManipulationCompletedRoutedEventArgs args) { base.OnManipulationCompleted(args); if (this.IsReadOnly || !this.IsPanEnabled) { return; } args.Handled = true; this.SetHighlightMode(false); var rectangle = new RadRect(args.Container.RenderSize.Width, args.Container.RenderSize.Height); if (this.freezeDisplayValue || rectangle.Contains(args.Position.X, args.Position.Y)) { this.Value = this.displayValue; this.freezeDisplayValue = false; } else { this.UpdateDisplayValue(); this.UpdateFillRatio(); } }
/// <summary> /// Clips the <paramref name="line"/> to the <paramref name="container"/>. /// </summary> /// <param name="line">The line to be clipped.</param> /// <param name="container">The container.</param> /// <param name="borderOverflow">The border (stroke thickness) of the <paramref name="line"/>.</param> /// <param name="dashPatternLength">The length of the dash pattern of the line stroke.</param> /// <returns>The clipped line.</returns> internal static RadLine ClipLine(RadLine line, RadRect container, double borderOverflow, double dashPatternLength) { // extend the container with the element border container.X -= borderOverflow; container.Y -= borderOverflow; container.Width += 2 * borderOverflow; container.Height += 2 * borderOverflow; bool firstPointInside = container.Contains(line.X1, line.Y1); bool secondPointInside = container.Contains(line.X2, line.Y2); if (firstPointInside && secondPointInside) { return(line); } if (dashPatternLength == 0 || double.IsNaN(dashPatternLength) || double.IsInfinity(dashPatternLength)) { dashPatternLength = 1; } // find intersectionns of the line with the sides of the container double topIntersectionX = RadMath.CalculateIntersectionX(line.X1, line.Y1, line.X2, line.Y2, container.Y); double bottomIntersectionX = RadMath.CalculateIntersectionX(line.X1, line.Y1, line.X2, line.Y2, container.Bottom); double leftIntersectionY = RadMath.CalculateIntersectionY(line.X1, line.Y1, line.X2, line.Y2, container.X); double rightIntersectionY = RadMath.CalculateIntersectionY(line.X1, line.Y1, line.X2, line.Y2, container.Right); // slope of the line: angle between the line ant the horizon (-pi/2, pi/2) var angle = Math.Atan((line.Y1 - line.Y2) / (line.X2 - line.X1)); bool intersectsWithRect = false; // clip to container sides intersectsWithRect |= AnnotationHelper.TryClipToContainerTop(ref line, container, topIntersectionX, dashPatternLength, angle > 0 ? angle : Math.PI + angle); intersectsWithRect |= AnnotationHelper.TryClipToContainerBottom(ref line, container, bottomIntersectionX, dashPatternLength, angle > 0 ? angle : Math.PI + angle); intersectsWithRect |= AnnotationHelper.TryClipToContainerLeft(ref line, container, leftIntersectionY, dashPatternLength, angle); intersectsWithRect |= AnnotationHelper.TryClipToContainerRight(ref line, container, rightIntersectionY, dashPatternLength, angle); if (!intersectsWithRect) { line = new RadLine(); } return(line); }
private void HandlePanManipulation(ManipulationDeltaRoutedEventArgs args) { var rectangle = new RadRect(args.Container.RenderSize.Width, args.Container.RenderSize.Height); var point = args.Position; var x = point.X; var y = point.Y; var dx = args.Delta.Translation.X; var dy = args.Delta.Translation.Y; var manipulationStartPointInside = rectangle.Contains(x, y); var manipulationEndPointInside = rectangle.Contains(x + dx, y + dy); if (!manipulationStartPointInside && !manipulationEndPointInside) { // pointer was outside during the whole manipulation, nothing should happen return; } if (manipulationEndPointInside) { // at the end the pointer is inside the container => handle point manipulation this.HandlePointManipulation(new Point(x + dx, y + dx)); } else { // the pointer has left the contained during the manipulation - should determine the direction var manipulationLeavingPointDirection = this.GetManipulationDirection(dy, dx, y, x, rectangle); this.HandleManipulationLeavesRating(manipulationLeavingPointDirection); if (this.freezeDisplayValue) { this.UpdateFillRatio(); } } }