/// <summary> /// Adds the handles for the given bezier point. /// </summary> /// <param name="index">The index of the <c>KimonoBezierPoint</c> that handles are /// being created for.</param> /// <param name="bezierPoint">The <c>KimonoBezierPoint</c> that is getting handles.</param> public void AddHandlesForPoint(int index, KimonoBezierPoint bezierPoint) { // Add new control point handle var controlPoint = new KimonoHandle(bezierPoint.ControlPoint.X - KimonoHandle.DrawOffset, bezierPoint.ControlPoint.Y - KimonoHandle.DrawOffset) { Index = index, HandleType = KimonoHandleType.BezierControlPoint }; controlPoint.Moved += (pt) => { // Move attached point Points[controlPoint.Index].ControlPoint = pt; }; ControlPoints.Add(controlPoint); // Add new end point handle var endPoint = new KimonoHandle(bezierPoint.EndPoint.X - KimonoHandle.DrawOffset, bezierPoint.EndPoint.Y - KimonoHandle.DrawOffset) { Index = index }; endPoint.Moved += (pt) => { // Move attached point Points[endPoint.Index].EndPoint = pt; }; ControlPoints.Add(endPoint); }
/// <summary> /// Test to see if the given point is inside of the current bounds /// </summary> /// <returns><c>true</c>, if in bounds, <c>false</c> otherwise.</returns> /// <param name="point">Point.</param> public virtual bool PointInBound(SKPoint point) { // Clear hit handle and test point HitHandle = null; var inBounds = (ValueBetween(point.X, Left, Right) && ValueBetween(point.Y, Top, Bottom)); // Test all handles to see if they have been hit if (TopLeftHandle != null && TopLeftHandle.PointInBound(point)) { HitHandle = TopLeftHandle; inBounds = true; } else if (TopHandle != null && TopHandle.PointInBound(point)) { HitHandle = TopHandle; inBounds = true; } else if (TopRightHandle != null && TopRightHandle.PointInBound(point)) { HitHandle = TopRightHandle; inBounds = true; } else if (RightHandle != null && RightHandle.PointInBound(point)) { HitHandle = RightHandle; inBounds = true; } else if (BottomRightHandle != null && BottomRightHandle.PointInBound(point)) { HitHandle = BottomRightHandle; inBounds = true; } else if (BottomHandle != null && BottomHandle.PointInBound(point)) { HitHandle = BottomHandle; inBounds = true; } else if (BottomLeftHandle != null && BottomLeftHandle.PointInBound(point)) { HitHandle = BottomLeftHandle; inBounds = true; } else if (LeftHandle != null && LeftHandle.PointInBound(point)) { HitHandle = LeftHandle; inBounds = true; } else if (inBounds) { // See if we are in bounds HitOffset = new SKPoint((Left > Right) ? point.X - Right : point.X - Left, (Top > Bottom) ? point.Y - Bottom : point.Y - Top); } return(inBounds); }
/// <summary> /// Removes the control handles from the bounds. /// </summary> internal void RemoveHandles() { // Remove all handles HitHandle = null; TopLeftHandle = null; TopHandle = null; TopRightHandle = null; RightHandle = null; BottomRightHandle = null; BottomHandle = null; BottomLeftHandle = null; LeftHandle = null; }
/// <summary> /// Clone this instance. /// </summary> /// <returns>The clone.</returns> public KimonoHandle Clone() { // Duplicate handle var newHandle = new KimonoHandle(this.X, this.Y) { Index = this.Index, HandleType = this.HandleType, UniqueID = this.UniqueID, State = this.State, Constraint = this.Constraint, Color = this.Color, LinkedColor = this.LinkedColor }; // Return new handle return(newHandle); }
/// <summary> /// Converts the given point to code using the given library. /// </summary> /// <returns>The point as code.</returns> /// <param name="outputLibrary">The `CodeOutputLibrary` to encode to.</param> /// <param name="point">The `KimonoHandle` to encode.</param> public static string PointToCode(CodeOutputLibrary outputLibrary, KimonoHandle point) { var sourceCode = ""; // Take action based on the language type switch (outputLibrary) { case CodeOutputLibrary.SkiaSharp: sourceCode = $"new SKPoint({point.X}f, {point.Y}f)"; break; case CodeOutputLibrary.KimonoCore: sourceCode = $"new KimonoHandle({point.X}f, {point.Y}f)"; break; } // Return results return(sourceCode); }
/// <summary> /// Places the shape into the editing mode where the user can adjust the individual data points /// that define the shape. /// </summary> public override void StartEditing() { base.StartEditing(); // Add the required control points ControlPoints.Clear(); for (int n = 0; n < Points.Count; ++n) { var point = Points[n]; var handle = new KimonoHandle(point.X - KimonoHandle.DrawOffset, point.Y - KimonoHandle.DrawOffset); handle.Index = n; handle.Moved += (pt) => { // Move attached point Points[handle.Index] = pt; }; ControlPoints.Add(handle); } }
/// <summary> /// Updates the location of the edit handles when the bounds has been relocated or /// resized. /// </summary> public virtual void BoundsChanged() { // Anything to process? if (TopLeftHandle == null) { return; } // Adjust the four courner drag handles TopLeftHandle.MoveTo(Left - KimonoHandle.DrawOffset, Top - KimonoHandle.DrawOffset); TopRightHandle.MoveTo(Right - KimonoHandle.DrawOffset, Top - KimonoHandle.DrawOffset); BottomRightHandle.MoveTo(Right - KimonoHandle.DrawOffset, Bottom - KimonoHandle.DrawOffset); BottomLeftHandle.MoveTo(Left - KimonoHandle.DrawOffset, Bottom - KimonoHandle.DrawOffset); // Set handle state var newHandleState = (State == KimonoShapeState.Selected) ? KimonoShapeState.Unselected : State; // Adjust top and bottom drag handles based on width if (Width < 50) { // Too small so remove handles TopHandle = null; BottomHandle = null; } else { // Move or create handles as needed if (TopHandle == null) { TopHandle = new KimonoHandle(HorizontalCenter - KimonoHandle.DrawOffset, Top - KimonoHandle.DrawOffset, KimonoHandleConstraint.Vertical, newHandleState); TopHandle.Moved += (point) => { Top = point.Y; }; } else { TopHandle.MoveTo(HorizontalCenter - KimonoHandle.DrawOffset, Top - KimonoHandle.DrawOffset); } if (BottomHandle == null) { BottomHandle = new KimonoHandle(HorizontalCenter - KimonoHandle.DrawOffset, Bottom - KimonoHandle.DrawOffset, KimonoHandleConstraint.Vertical, newHandleState); BottomHandle.Moved += (point) => { Bottom = point.Y; }; } else { BottomHandle.MoveTo(HorizontalCenter - KimonoHandle.DrawOffset, Bottom - KimonoHandle.DrawOffset); } } // Adjust left and right drag handles based on the height if (Height < 50) { // Too small so remove handles LeftHandle = null; RightHandle = null; } else { // Move or create handles as needed if (LeftHandle == null) { LeftHandle = new KimonoHandle(Left - KimonoHandle.DrawOffset, VerticalCenter - KimonoHandle.DrawOffset, KimonoHandleConstraint.Horizontal, newHandleState); LeftHandle.Moved += (point) => { Left = point.X; }; } else { LeftHandle.MoveTo(Left - KimonoHandle.DrawOffset, VerticalCenter - KimonoHandle.DrawOffset); } if (RightHandle == null) { RightHandle = new KimonoHandle(Right - KimonoHandle.DrawOffset, VerticalCenter - KimonoHandle.DrawOffset, KimonoHandleConstraint.Horizontal, newHandleState); RightHandle.Moved += (point) => { Right = point.X; }; } else { RightHandle.MoveTo(Right - KimonoHandle.DrawOffset, VerticalCenter - KimonoHandle.DrawOffset); } } }
/// <summary> /// Adds the control handles to the bounds /// </summary> internal void AddHandles(KimonoShapeState state) { // Create the four corner drag handles TopLeftHandle = new KimonoHandle(Left - KimonoHandle.DrawOffset, Top - KimonoHandle.DrawOffset, state); TopRightHandle = new KimonoHandle(Right - KimonoHandle.DrawOffset, Top - KimonoHandle.DrawOffset, state); BottomRightHandle = new KimonoHandle(Right - KimonoHandle.DrawOffset, Bottom - KimonoHandle.DrawOffset, state); BottomLeftHandle = new KimonoHandle(Left - KimonoHandle.DrawOffset, Bottom - KimonoHandle.DrawOffset, state); // Wire-up events TopLeftHandle.Moved += (point) => { SavePreviousBounds(); Rect.Left = point.X; Rect.Top = point.Y; BoundsChanged(); }; TopRightHandle.Moved += (point) => { SavePreviousBounds(); Rect.Right = point.X; Rect.Top = point.Y; BoundsChanged(); }; BottomRightHandle.Moved += (point) => { SavePreviousBounds(); Rect.Right = point.X; Rect.Bottom = point.Y; BoundsChanged(); }; BottomLeftHandle.Moved += (point) => { SavePreviousBounds(); Rect.Left = point.X; Rect.Bottom = point.Y; BoundsChanged(); }; // Create the top and bottom drag handles if the bounds // is wide enough if (Width >= 50) { // Add handles TopHandle = new KimonoHandle(HorizontalCenter - KimonoHandle.DrawOffset, Top - KimonoHandle.DrawOffset, KimonoHandleConstraint.Vertical, state); BottomHandle = new KimonoHandle(HorizontalCenter - KimonoHandle.DrawOffset, Bottom - KimonoHandle.DrawOffset, KimonoHandleConstraint.Vertical, state); // Wire-up events TopHandle.Moved += (point) => { Top = point.Y; }; BottomHandle.Moved += (point) => { Bottom = point.Y; }; } // Create the left and right drag handles if the bounds // is tall enough if (Height >= 50) { // Add handle LeftHandle = new KimonoHandle(Left - KimonoHandle.DrawOffset, VerticalCenter - KimonoHandle.DrawOffset, KimonoHandleConstraint.Horizontal, state); RightHandle = new KimonoHandle(Right - KimonoHandle.DrawOffset, VerticalCenter - KimonoHandle.DrawOffset, KimonoHandleConstraint.Horizontal, state); // Wire-up events LeftHandle.Moved += (point) => { Left = point.X; }; RightHandle.Moved += (point) => { Right = point.X; }; } }