protected sealed override void RenderPoints([NotNull] IDrawingContext drawingContext, ref Rect clippingRect, bool isCurrentCurve) { var controlPointCount = controlPoints.Count; if (controlPointCount == 0) { drawingContext.DrawTexts(new[] { clippingRect.GetCenterLocation() }, Color.LightGray, new[] { $"{Resources.Strings.KeyGestures.GestureAddPoint} to add a keyframe" }, XAxis.FontFamily, XAxis.FontSize * 2, FontWeights.Bold, HorizontalAlignment.Center, VerticalAlignment.Center); return; } #if DEBUG_POINTS_ORDER var sortedPoints = new List <KeyFrameControlPointViewModel <TValue> >(controlPoints.Count); var firstPoint = controlPoints[0]; while (firstPoint != null) { sortedPoints.Add(firstPoint); firstPoint = firstPoint.Next as KeyFrameControlPointViewModel <TValue>; } #else // control points can temporarily be unordered during the dragging of one or more points var sortedPoints = controlPoints.OrderBy(p => p.ActualPoint.X).ToList(); #endif // sample the curve var drawPoints = new List <WindowsPoint>(); for (var i = 0; i < controlPointCount - 1; ++i) { var samples = SampleControlPoints(sortedPoints[i], sortedPoints[i + 1]); drawPoints.AddRange(samples.Select(TransformPoint)); } // last point drawPoints.Add(sortedPoints[controlPoints.Count - 1].ActualPoint); // render the curve RenderLine(drawingContext, ref clippingRect, drawPoints, Color); if (!isCurrentCurve) { return; } // Retrieve actual points (and selected actual points) var actualPoints = new List <WindowsPoint>(); var selectedActualPoints = new List <WindowsPoint>(); foreach (var controlPoint in controlPoints) { var actualPoint = controlPoint.ActualPoint; actualPoints.Add(actualPoint); if (controlPoint.IsSelected) { selectedActualPoints.Add(actualPoint); } } // Render the control points var radius = ControlPointRadius; drawingContext.DrawCircles(actualPoints, radius, ControlPointColor, ControlPointColor); // Render the selection circles over the selected control points radius *= 2; drawingContext.DrawCircles(selectedActualPoints, radius, Color.Transparent, Color.WhiteSmoke); // Render the tangents // TODO: also render tangents }