aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Beltran del Rio <git@r.bdr.sh>2025-07-08 09:41:13 +0200
committerRuben Beltran del Rio <git@r.bdr.sh>2025-07-08 09:41:13 +0200
commit68c53f41cf165e42f40e12fe724043b014bc9b68 (patch)
tree2d26ce8f97a963b4a4a145413765e9fe5cf04a89
parent96a65922a562c59b792704dfae62119f4bf1560f (diff)
Add draggong logic to vertices
-rw-r--r--Map/Presentation/Base Components/MapRender/MapVertices.swift62
1 files changed, 52 insertions, 10 deletions
diff --git a/Map/Presentation/Base Components/MapRender/MapVertices.swift b/Map/Presentation/Base Components/MapRender/MapVertices.swift
index e6617b3..8b5dde2 100644
--- a/Map/Presentation/Base Components/MapRender/MapVertices.swift
+++ b/Map/Presentation/Base Components/MapRender/MapVertices.swift
@@ -22,13 +22,50 @@ struct MapVertices: View {
let labelPositions: [Int: CGPoint]
let padding = CGFloat(5.0)
+ @State private var offset = CGSize.zero
+ @State private var draggingVertex: Vertex? = nil
+
var onDragVertex: (Vertex, CGFloat, CGFloat) -> Void = { _, _, _ in }
var body: some View {
ZStack(alignment: .topLeading) {
ForEach(vertices, id: \.id) { vertex in
ZStack(alignment: .topLeading) {
- getVertexShape(vertex).fill(Color.Theme.Map.vertexColor)
+ getVertexShape(vertex)
+ .fill(Color.Theme.Map.vertexColor)
+ .offset(
+ x: vertex == draggingVertex ? offset.width : 0,
+ y: vertex == draggingVertex ? offset.height : 0)
+
+ // Drag Hit box. Path bounds seem to be infinite.
+ Rectangle()
+ .fill(Color.black.opacity(0.001))
+ .frame(width: vertexSize.width, height: vertexSize.height)
+ .offset(x: w(vertex.position.x), y: h(vertex.position.y))
+ .onHover { isHovering in
+ if isHovering {
+ NSCursor.pointingHand.set()
+ } else {
+ NSCursor.arrow.set()
+ }
+ }
+ .gesture(
+ DragGesture()
+ .onChanged { value in
+ offset = value.translation
+ draggingVertex = vertex
+ NSCursor.closedHand.set()
+ }
+ .onEnded { value in
+ let newX = mw(w(vertex.position.x) + value.translation.width)
+ let newY = mh(h(vertex.position.y) + value.translation.height)
+
+ onDragVertex(vertex, newX, newY)
+
+ NSCursor.arrow.set()
+ }
+ )
+
Text(vertex.label.replacingOccurrences(of: "\\n", with: "\n"))
.font(.Theme.Map.vertexLabel)
.lineSpacing(
@@ -39,15 +76,12 @@ struct MapVertices: View {
CGSize(
width: labelPositions[vertex.id]?.x
?? (w(vertex.position.x) + vertexSize.width + padding),
- height: labelPositions[vertex.id]?.y ?? (h(vertex.position.y) + 7.0)))
- }.gesture(
- DragGesture()
- .onChanged { value in
- let deltaX = value.startLocation.x - value.location.x
- let deltaY = value.startLocation.y - value.location.y
- onDragVertex(vertex, deltaX, deltaY)
- }
- )
+ height: labelPositions[vertex.id]?.y ?? (h(vertex.position.y) + 7.0))
+ )
+ .offset(
+ x: vertex == draggingVertex ? offset.width : 0,
+ y: vertex == draggingVertex ? offset.height : 0)
+ }
}
}
}
@@ -60,6 +94,14 @@ struct MapVertices: View {
max(0.0, min(mapSize.width, dimension * mapSize.width / 100.0))
}
+ func mh(_ dimension: CGFloat) -> CGFloat {
+ max(0.0, min(100, dimension * 100 / mapSize.height))
+ }
+
+ func mw(_ dimension: CGFloat) -> CGFloat {
+ max(0.0, min(100, dimension * 100 / mapSize.width))
+ }
+
func getVertexShape(_ vertex: Vertex) -> Path {
switch vertex.shape {
case .circle: