|
@@ -76,6 +76,7 @@ public class VectorPathOverlay : Overlay
|
|
AddHandle(transformHandle);
|
|
AddHandle(transformHandle);
|
|
|
|
|
|
insertPreviewHandle = new AnchorHandle(this);
|
|
insertPreviewHandle = new AnchorHandle(this);
|
|
|
|
+ insertPreviewHandle.HitTestVisible = false;
|
|
|
|
|
|
AddHandle(insertPreviewHandle);
|
|
AddHandle(insertPreviewHandle);
|
|
}
|
|
}
|
|
@@ -134,8 +135,12 @@ public class VectorPathOverlay : Overlay
|
|
|
|
|
|
foreach (var point in subPath.Points)
|
|
foreach (var point in subPath.Points)
|
|
{
|
|
{
|
|
|
|
+ if (anchorIndex >= anchorHandles.Count)
|
|
|
|
+ {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
var handle = anchorHandles[anchorIndex];
|
|
var handle = anchorHandles[anchorIndex];
|
|
- //handle.Position = (VecD)point.Position;
|
|
|
|
|
|
|
|
if (point.Verb.ControlPoint1 != null || point.Verb.ControlPoint2 != null)
|
|
if (point.Verb.ControlPoint1 != null || point.Verb.ControlPoint2 != null)
|
|
{
|
|
{
|
|
@@ -186,6 +191,11 @@ public class VectorPathOverlay : Overlay
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public override bool TestHit(VecD point)
|
|
|
|
+ {
|
|
|
|
+ return Path != null;
|
|
|
|
+ }
|
|
|
|
+
|
|
private void AdjustHandles(EditableVectorPath path)
|
|
private void AdjustHandles(EditableVectorPath path)
|
|
{
|
|
{
|
|
int pointsCount = path.TotalPoints + path.ControlPointsCount;
|
|
int pointsCount = path.TotalPoints + path.ControlPointsCount;
|
|
@@ -210,7 +220,6 @@ public class VectorPathOverlay : Overlay
|
|
CreateHandle(controlPointHandles.Count, true);
|
|
CreateHandle(controlPointHandles.Count, true);
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
SelectAnchor(GetHandleAt(pointsCount - 1));
|
|
SelectAnchor(GetHandleAt(pointsCount - 1));
|
|
|
|
|
|
ConnectControlPointsToAnchors();
|
|
ConnectControlPointsToAnchors();
|
|
@@ -239,6 +248,8 @@ public class VectorPathOverlay : Overlay
|
|
controlPointIndex += 2;
|
|
controlPointIndex += 2;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (anchorIndex >= anchorHandles.Count) continue;
|
|
|
|
+
|
|
var anchor = anchorHandles[anchorIndex];
|
|
var anchor = anchorHandles[anchorIndex];
|
|
anchor.Position = (VecD)point.Position;
|
|
anchor.Position = (VecD)point.Position;
|
|
anchorIndex++;
|
|
anchorIndex++;
|
|
@@ -383,30 +394,46 @@ public class VectorPathOverlay : Overlay
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- if (Path.IsClosed)
|
|
|
|
|
|
+ if (args.Modifiers.HasFlag(KeyModifiers.Control))
|
|
{
|
|
{
|
|
|
|
+ SelectAnchor(anchorHandle);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- VectorPath newPath = new VectorPath(Path);
|
|
|
|
- if (args.Modifiers.HasFlag(KeyModifiers.Control))
|
|
|
|
|
|
+ var selectedHandle = anchorHandles.FirstOrDefault(h => h.IsSelected);
|
|
|
|
+ if (selectedHandle == null)
|
|
{
|
|
{
|
|
- SelectAnchor(anchorHandle);
|
|
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- if (anchorHandles.IndexOf(anchorHandle) == 0)
|
|
|
|
|
|
+ SubShape ssOfSelected = editableVectorPath.GetSubShapeContainingIndex(anchorHandles.IndexOf(selectedHandle));
|
|
|
|
+ SubShape ssOfTapped = editableVectorPath.GetSubShapeContainingIndex(anchorHandles.IndexOf(anchorHandle));
|
|
|
|
+
|
|
|
|
+ if(ssOfTapped == null || ssOfSelected == null)
|
|
{
|
|
{
|
|
- newPath.LineTo((VecF)anchorHandle.Position);
|
|
|
|
- newPath.Close();
|
|
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int globalIndexOfTapped = anchorHandles.IndexOf(anchorHandle);
|
|
|
|
+ int localIndexOfTapped = editableVectorPath.GetSubShapePointIndex(globalIndexOfTapped, ssOfTapped);
|
|
|
|
+
|
|
|
|
+ if (ssOfSelected == ssOfTapped && ssOfTapped.IsClosed)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (ssOfSelected == ssOfTapped && !ssOfTapped.IsClosed &&
|
|
|
|
+ (localIndexOfTapped == 0 || localIndexOfTapped == ssOfTapped.Points.Count - 1))
|
|
|
|
+ {
|
|
|
|
+ ssOfTapped.Close();
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- VecD pos = anchorHandle.Position;
|
|
|
|
- newPath.LineTo(new VecF((float)pos.X, (float)pos.Y));
|
|
|
|
|
|
+ ssOfTapped.AppendPoint((VecF)anchorHandle.Position);
|
|
}
|
|
}
|
|
|
|
|
|
- Path = newPath;
|
|
|
|
|
|
+ SelectAnchor(anchorHandle);
|
|
|
|
+ Path = editableVectorPath.ToVectorPath();
|
|
}
|
|
}
|
|
|
|
|
|
private void SelectAnchor(AnchorHandle handle)
|
|
private void SelectAnchor(AnchorHandle handle)
|
|
@@ -419,12 +446,21 @@ public class VectorPathOverlay : Overlay
|
|
|
|
|
|
protected override void OnOverlayPointerPressed(OverlayPointerArgs args)
|
|
protected override void OnOverlayPointerPressed(OverlayPointerArgs args)
|
|
{
|
|
{
|
|
|
|
+ if(args.PointerButton != MouseButton.Left)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (args.Modifiers.HasFlag(KeyModifiers.Shift) && IsOverPath(args.Point, out VecD closestPoint))
|
|
if (args.Modifiers.HasFlag(KeyModifiers.Shift) && IsOverPath(args.Point, out VecD closestPoint))
|
|
{
|
|
{
|
|
AddPointAt(closestPoint);
|
|
AddPointAt(closestPoint);
|
|
AddToUndoCommand.Execute(Path);
|
|
AddToUndoCommand.Execute(Path);
|
|
args.Handled = true;
|
|
args.Handled = true;
|
|
}
|
|
}
|
|
|
|
+ else if (args.Modifiers == KeyModifiers.None)
|
|
|
|
+ {
|
|
|
|
+ AddNewPointFromClick(args.Point);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
protected override void OnOverlayPointerMoved(OverlayPointerArgs args)
|
|
protected override void OnOverlayPointerMoved(OverlayPointerArgs args)
|
|
@@ -440,6 +476,30 @@ public class VectorPathOverlay : Overlay
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private void AddNewPointFromClick(VecD point)
|
|
|
|
+ {
|
|
|
|
+ var selectedHandle = anchorHandles.FirstOrDefault(h => h.IsSelected);
|
|
|
|
+ SubShape subShape = editableVectorPath.GetSubShapeContainingIndex(anchorHandles.IndexOf(selectedHandle));
|
|
|
|
+
|
|
|
|
+ if (subShape.IsClosed)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (Path.IsEmpty)
|
|
|
|
+ {
|
|
|
|
+ Path = new VectorPath();
|
|
|
|
+ Path.LineTo((VecF)point);
|
|
|
|
+ SelectAnchor(anchorHandles[0]);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ subShape.AppendPoint((VecF)point);
|
|
|
|
+ Path = editableVectorPath.ToVectorPath();
|
|
|
|
+ SelectAnchor(anchorHandles.Last());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
private void AddPointAt(VecD point)
|
|
private void AddPointAt(VecD point)
|
|
{
|
|
{
|
|
editableVectorPath.AddPointAt(point);
|
|
editableVectorPath.AddPointAt(point);
|
|
@@ -459,8 +519,10 @@ public class VectorPathOverlay : Overlay
|
|
if (source is AnchorHandle anchorHandle)
|
|
if (source is AnchorHandle anchorHandle)
|
|
{
|
|
{
|
|
SnappingController.RemoveAll($"editingPath[{anchorHandles.IndexOf(anchorHandle)}]");
|
|
SnappingController.RemoveAll($"editingPath[{anchorHandles.IndexOf(anchorHandle)}]");
|
|
|
|
+ SelectAnchor(anchorHandle);
|
|
CaptureHandle(source);
|
|
CaptureHandle(source);
|
|
-
|
|
|
|
|
|
+ args.Handled = true;
|
|
|
|
+
|
|
if (!args.Modifiers.HasFlag(KeyModifiers.Control)) return;
|
|
if (!args.Modifiers.HasFlag(KeyModifiers.Control)) return;
|
|
|
|
|
|
var newPath = ConvertTouchingVerbsToCubic(anchorHandle);
|
|
var newPath = ConvertTouchingVerbsToCubic(anchorHandle);
|
|
@@ -472,6 +534,7 @@ public class VectorPathOverlay : Overlay
|
|
HandleContinousCubicDrag(anchorHandle.Position, anchorHandle, subShapeContainingIndex, localIndex, true);
|
|
HandleContinousCubicDrag(anchorHandle.Position, anchorHandle, subShapeContainingIndex, localIndex, true);
|
|
|
|
|
|
Path = newPath.ToVectorPath();
|
|
Path = newPath.ToVectorPath();
|
|
|
|
+
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|