aboutsummaryrefslogtreecommitdiff
path: root/Map/Presentation/Base Components/MapRender
diff options
context:
space:
mode:
Diffstat (limited to 'Map/Presentation/Base Components/MapRender')
-rw-r--r--Map/Presentation/Base Components/MapRender/MapAxes.swift24
-rw-r--r--Map/Presentation/Base Components/MapRender/MapBlockers.swift16
-rw-r--r--Map/Presentation/Base Components/MapRender/MapEdges.swift20
-rw-r--r--Map/Presentation/Base Components/MapRender/MapGroup.swift83
-rw-r--r--Map/Presentation/Base Components/MapRender/MapGroups.swift32
-rw-r--r--Map/Presentation/Base Components/MapRender/MapNotes.swift22
-rw-r--r--Map/Presentation/Base Components/MapRender/MapOpportunities.swift19
-rw-r--r--Map/Presentation/Base Components/MapRender/MapStages.swift49
-rw-r--r--Map/Presentation/Base Components/MapRender/MapVertices.swift41
9 files changed, 219 insertions, 87 deletions
diff --git a/Map/Presentation/Base Components/MapRender/MapAxes.swift b/Map/Presentation/Base Components/MapRender/MapAxes.swift
index 6ba758f..1b9c226 100644
--- a/Map/Presentation/Base Components/MapRender/MapAxes.swift
+++ b/Map/Presentation/Base Components/MapRender/MapAxes.swift
@@ -22,10 +22,14 @@ struct MapAxes: View {
}.stroke(Color.map.axisColor, lineWidth: lineWidth * 2)
// Y Labels
- Text("Visible").font(.theme.axisLabel).foregroundColor(.map.labelColor).rotationEffect(Angle(degrees: -90.0))
- .offset(CGSize(width: -35.0, height: 0.0))
- Text("Invisible").font(.theme.axisLabel).foregroundColor(.map.labelColor).rotationEffect(Angle(degrees: -90.0))
- .offset(CGSize(width: -40.0, height: mapSize.height - 20))
+ Text("Visible").font(.theme.axisLabel).foregroundColor(.map.labelColor).rotationEffect(
+ Angle(degrees: -90.0)
+ )
+ .offset(CGSize(width: -35.0, height: 0.0))
+ Text("Invisible").font(.theme.axisLabel).foregroundColor(.map.labelColor).rotationEffect(
+ Angle(degrees: -90.0)
+ )
+ .offset(CGSize(width: -40.0, height: mapSize.height - 20))
// X Labels
@@ -71,11 +75,9 @@ struct MapAxes: View {
}
}
-struct MapAxes_Previews: PreviewProvider {
- static var previews: some View {
- MapAxes(
- mapSize: CGSize(width: 200.0, height: 200.0), lineWidth: CGFloat(1.0),
- evolution: Stage.stages(.general), stages: [25.0, 50.0, 75.0]
- ).padding(50.0)
- }
+#Preview {
+ MapAxes(
+ mapSize: CGSize(width: 200.0, height: 200.0), lineWidth: CGFloat(1.0),
+ evolution: Stage.stages(.general), stages: [25.0, 50.0, 75.0]
+ ).padding(50.0)
}
diff --git a/Map/Presentation/Base Components/MapRender/MapBlockers.swift b/Map/Presentation/Base Components/MapRender/MapBlockers.swift
index d943ba8..efd84fa 100644
--- a/Map/Presentation/Base Components/MapRender/MapBlockers.swift
+++ b/Map/Presentation/Base Components/MapRender/MapBlockers.swift
@@ -31,13 +31,11 @@ struct MapBlockers: View {
}
}
-struct MapBlockers_Previews: PreviewProvider {
- static var previews: some View {
- MapBlockers(
- mapSize: CGSize(width: 400.0, height: 400.0), vertexSize: CGSize(width: 25.0, height: 25.0),
- blockers: [
- Blocker(id: 0, position: CGPoint(x: 50.0, y: 50.0)),
- Blocker(id: 1, position: CGPoint(x: 10.0, y: 20.0)),
- ])
- }
+#Preview {
+ MapBlockers(
+ mapSize: CGSize(width: 400.0, height: 400.0), vertexSize: CGSize(width: 25.0, height: 25.0),
+ blockers: [
+ Blocker(id: 0, position: CGPoint(x: 50.0, y: 50.0)),
+ Blocker(id: 1, position: CGPoint(x: 10.0, y: 20.0)),
+ ])
}
diff --git a/Map/Presentation/Base Components/MapRender/MapEdges.swift b/Map/Presentation/Base Components/MapRender/MapEdges.swift
index 3814495..2af7089 100644
--- a/Map/Presentation/Base Components/MapRender/MapEdges.swift
+++ b/Map/Presentation/Base Components/MapRender/MapEdges.swift
@@ -65,15 +65,13 @@ struct MapEdges: View {
}
}
-struct MapEdges_Previews: PreviewProvider {
- static var previews: some View {
- MapEdges(
- mapSize: CGSize(width: 400.0, height: 400.0), lineWidth: 1.0,
- vertexSize: CGSize(width: 25.0, height: 25.0),
- edges: [
- MapEdge(
- id: 1, origin: CGPoint(x: 2.0, y: 34.0), destination: CGPoint(x: 23.0, y: 76.2),
- arrowhead: true)
- ])
- }
+#Preview {
+ MapEdges(
+ mapSize: CGSize(width: 400.0, height: 400.0), lineWidth: 1.0,
+ vertexSize: CGSize(width: 25.0, height: 25.0),
+ edges: [
+ MapEdge(
+ id: 1, origin: CGPoint(x: 2.0, y: 34.0), destination: CGPoint(x: 23.0, y: 76.2),
+ arrowhead: true)
+ ])
}
diff --git a/Map/Presentation/Base Components/MapRender/MapGroup.swift b/Map/Presentation/Base Components/MapRender/MapGroup.swift
new file mode 100644
index 0000000..9df3338
--- /dev/null
+++ b/Map/Presentation/Base Components/MapRender/MapGroup.swift
@@ -0,0 +1,83 @@
+import ConcaveHull
+import SwiftUI
+
+struct MapGroup: View {
+
+ let mapSize: CGSize
+ let vertexSize: CGSize
+ let group: [Vertex]
+ let color: Color
+
+ let cornerSize = CGSize(width: 2.0, height: 2.0)
+ var strokeSize: CGFloat { 1.75 * vertexSize.width }
+
+ var hull: [CGPoint] {
+ let groupList = group.map({ vertex in
+ return [Double(vertex.position.x), Double(vertex.position.y)]
+ })
+ let hull = Hull()
+ let hullPoints = hull.hull(groupList, nil)
+ return hullPoints.compactMap({ object in
+ if let point = object as? [Double] {
+ return CGPoint(x: point[0], y: point[1])
+ }
+ return nil
+ })
+ }
+
+ var body: some View {
+ Path { path in
+ var initialMove: CGPoint?
+
+ for point in hull {
+ let offsetPoint = CGPoint(x: w(point.x), y: h(point.y))
+
+ if initialMove == nil {
+ path.move(to: offsetPoint)
+ initialMove = offsetPoint
+ } else {
+ path.addLine(to: offsetPoint)
+ }
+ }
+
+ if let initialMove = initialMove {
+ path.addLine(to: initialMove)
+ }
+
+ }
+ .applying(
+ CGAffineTransform(translationX: vertexSize.width / 2.0, y: vertexSize.height / 2.0)
+ )
+ .fill(color)
+ .stroke(
+ color,
+ style: StrokeStyle(
+ lineWidth: strokeSize,
+ lineCap: .round,
+ lineJoin: .round,
+ miterLimit: 0,
+ dash: [],
+ dashPhase: 0
+ )
+ )
+ }
+
+ func h(_ dimension: CGFloat) -> CGFloat {
+ max(0.0, min(mapSize.height, dimension * mapSize.height / 100.0))
+ }
+
+ func w(_ dimension: CGFloat) -> CGFloat {
+ max(0.0, min(mapSize.width, dimension * mapSize.width / 100.0))
+ }
+}
+
+#Preview {
+ MapGroup(
+ mapSize: CGSize(width: 400.0, height: 400.0), vertexSize: CGSize(width: 25.0, height: 25.0),
+ group: [
+ Vertex(id: 0, label: "A Circle", position: CGPoint(x: 50.0, y: 50.0)),
+ Vertex(id: 1, label: "A Square", position: CGPoint(x: 10.0, y: 20.0), shape: .square),
+ Vertex(id: 2, label: "A triangle", position: CGPoint(x: 25, y: 32.0), shape: .triangle),
+ Vertex(id: 3, label: "An X", position: CGPoint(x: 70.0, y: 70.0), shape: .x),
+ ], color: .red)
+}
diff --git a/Map/Presentation/Base Components/MapRender/MapGroups.swift b/Map/Presentation/Base Components/MapRender/MapGroups.swift
new file mode 100644
index 0000000..84f7fb2
--- /dev/null
+++ b/Map/Presentation/Base Components/MapRender/MapGroups.swift
@@ -0,0 +1,32 @@
+import ConcaveHull
+import SwiftUI
+
+struct MapGroups: View {
+
+ let mapSize: CGSize
+ let vertexSize: CGSize
+ let groups: [[Vertex]]
+
+ var body: some View {
+ ForEach(Array(groups.enumerated()), id: \.element) { index, group in
+ MapGroup(mapSize: mapSize, vertexSize: vertexSize, group: group, color: color(index))
+ }
+ }
+
+ private func color(_ index: Int) -> Color {
+ return .map.groupColors[index % Color.map.groupColors.count]
+ }
+}
+
+#Preview {
+ MapGroups(
+ mapSize: CGSize(width: 400.0, height: 400.0), vertexSize: CGSize(width: 25.0, height: 25.0),
+ groups: [
+ [
+ Vertex(id: 0, label: "A Circle", position: CGPoint(x: 50.0, y: 50.0)),
+ Vertex(id: 1, label: "A Square", position: CGPoint(x: 10.0, y: 20.0), shape: .square),
+ Vertex(id: 2, label: "A triangle", position: CGPoint(x: 25, y: 32.0), shape: .triangle),
+ Vertex(id: 3, label: "An X", position: CGPoint(x: 70.0, y: 70.0), shape: .x),
+ ]
+ ])
+}
diff --git a/Map/Presentation/Base Components/MapRender/MapNotes.swift b/Map/Presentation/Base Components/MapRender/MapNotes.swift
index f35b3fe..bbb1aba 100644
--- a/Map/Presentation/Base Components/MapRender/MapNotes.swift
+++ b/Map/Presentation/Base Components/MapRender/MapNotes.swift
@@ -5,13 +5,12 @@ struct MapNotes: View {
let mapSize: CGSize
let lineWidth: CGFloat
let notes: [Note]
-
+
let maxWidth = 400.0
-
var body: some View {
ForEach(notes, id: \.id) { note in
- Text(note.text.replacingOccurrences(of: "\\n", with: "\n")).font(.theme.axisLabel)
+ Text(note.text.replacingOccurrences(of: "\\n", with: "\n")).font(.theme.note)
.padding(2.0)
.background(.white)
.foregroundColor(.map.labelColor)
@@ -35,12 +34,13 @@ struct MapNotes: View {
}
}
-struct MapNotes_Previews: PreviewProvider {
- static var previews: some View {
- MapNotes(
- mapSize: CGSize(width: 400.0, height: 400.0), lineWidth: 1.0,
- notes: [
- Note(id: 0, position: CGPoint(x: 50.0, y: 50.0), text: "Notes can have a lot more text, so we need to make sure that they're resized correctly"),
- ])
- }
+#Preview {
+ MapNotes(
+ mapSize: CGSize(width: 400.0, height: 400.0), lineWidth: 1.0,
+ notes: [
+ Note(
+ id: 0, position: CGPoint(x: 50.0, y: 50.0),
+ text:
+ "Notes can have a lot more text, so we need to make sure that they're resized correctly")
+ ])
}
diff --git a/Map/Presentation/Base Components/MapRender/MapOpportunities.swift b/Map/Presentation/Base Components/MapRender/MapOpportunities.swift
index 7fcadff..b3051ee 100644
--- a/Map/Presentation/Base Components/MapRender/MapOpportunities.swift
+++ b/Map/Presentation/Base Components/MapRender/MapOpportunities.swift
@@ -46,7 +46,8 @@ struct MapOpportunities: View {
path.closeSubpath()
}.applying(
CGAffineTransform(translationX: vertexSize.width / 2.0, y: vertexSize.height / 2.0)
- ).strokedPath(StrokeStyle(lineWidth: lineWidth / 4, dash: [10.0])).stroke(Color.map.opportunityColor)
+ ).strokedPath(StrokeStyle(lineWidth: lineWidth / 4, dash: [10.0])).stroke(
+ Color.map.opportunityColor)
}
}
@@ -59,13 +60,11 @@ struct MapOpportunities: View {
}
}
-struct MapOpportunities_Previews: PreviewProvider {
- static var previews: some View {
- MapOpportunities(
- mapSize: CGSize(width: 400.0, height: 400.0), lineWidth: 1.0,
- vertexSize: CGSize(width: 25.0, height: 25.0),
- opportunities: [
- Opportunity(id: 1, origin: CGPoint(x: 2.0, y: 34.0), destination: CGPoint(x: 23.0, y: 76.2))
- ])
- }
+#Preview {
+ MapOpportunities(
+ mapSize: CGSize(width: 400.0, height: 400.0), lineWidth: 1.0,
+ vertexSize: CGSize(width: 25.0, height: 25.0),
+ opportunities: [
+ Opportunity(id: 1, origin: CGPoint(x: 2.0, y: 34.0), destination: CGPoint(x: 23.0, y: 76.2))
+ ])
}
diff --git a/Map/Presentation/Base Components/MapRender/MapStages.swift b/Map/Presentation/Base Components/MapRender/MapStages.swift
index 0fc8f48..fc3bfa1 100644
--- a/Map/Presentation/Base Components/MapRender/MapStages.swift
+++ b/Map/Presentation/Base Components/MapRender/MapStages.swift
@@ -1,5 +1,5 @@
-import SwiftUI
import Patterns
+import SwiftUI
struct MapStages: View {
@@ -10,17 +10,29 @@ struct MapStages: View {
var body: some View {
ZStack(alignment: .topLeading) {
- PatternView(design: .constant(.stitch), pixelSize: 1.0, foregroundColor: .map.stageForeground, backgroundColor: .map.stageBackground)
- .frame(width: w(stages[0]), height: mapSize.height)
- PatternView(design: .constant(.shingles), pixelSize: 1.0, foregroundColor: .map.stageForeground, backgroundColor: .map.stageBackground)
- .offset(CGSize(width: w(stages[0]), height: 0))
- .frame(width: w(stages[1]) - w(stages[0]), height: mapSize.height)
- PatternView(design: .constant(.shadowGrid), pixelSize: 1.0, foregroundColor: .map.stageForeground, backgroundColor: .map.stageBackground)
- .offset(CGSize(width: w(stages[1]), height: 0))
- .frame(width: w(stages[2]) - w(stages[1]), height: mapSize.height)
- PatternView(design: .constant(.wicker), pixelSize: 1.0, foregroundColor: .map.stageForeground, backgroundColor: .map.stageBackground)
- .offset(CGSize(width: w(stages[2]), height: 0))
- .frame(width: mapSize.width - w(stages[2]), height: mapSize.height)
+ PatternView(
+ design: .constant(.stitch), pixelSize: 1.0, foregroundColor: .map.stageForeground,
+ backgroundColor: .map.stageBackground
+ )
+ .frame(width: w(stages[0]), height: mapSize.height)
+ PatternView(
+ design: .constant(.shingles), pixelSize: 1.0, foregroundColor: .map.stageForeground,
+ backgroundColor: .map.stageBackground
+ )
+ .offset(CGSize(width: w(stages[0]), height: 0))
+ .frame(width: w(stages[1]) - w(stages[0]), height: mapSize.height)
+ PatternView(
+ design: .constant(.shadowGrid), pixelSize: 1.0, foregroundColor: .map.stageForeground,
+ backgroundColor: .map.stageBackground
+ )
+ .offset(CGSize(width: w(stages[1]), height: 0))
+ .frame(width: w(stages[2]) - w(stages[1]), height: mapSize.height)
+ PatternView(
+ design: .constant(.wicker), pixelSize: 1.0, foregroundColor: .map.stageForeground,
+ backgroundColor: .map.stageBackground
+ )
+ .offset(CGSize(width: w(stages[2]), height: 0))
+ .frame(width: mapSize.width - w(stages[2]), height: mapSize.height)
Path { path in
path.move(to: CGPoint(x: w(stages[0]), y: 0))
@@ -34,7 +46,8 @@ struct MapStages: View {
path.closeSubpath()
path.move(to: CGPoint(x: w(stages[0]), y: 0))
path.closeSubpath()
- }.strokedPath(StrokeStyle(lineWidth: lineWidth / 4, dash: [10.0, 18.0])).stroke(Color.map.axisColor)
+ }.strokedPath(StrokeStyle(lineWidth: lineWidth / 4, dash: [10.0, 18.0])).stroke(
+ Color.map.axisColor)
}
}
@@ -43,10 +56,8 @@ struct MapStages: View {
}
}
-struct MapStages_Previews: PreviewProvider {
- static var previews: some View {
- MapStages(
- mapSize: CGSize(width: 200.0, height: 200.0), lineWidth: CGFloat(0.5),
- stages: [25.0, 50.0, 75.0])
- }
+#Preview {
+ MapStages(
+ mapSize: CGSize(width: 200.0, height: 200.0), lineWidth: CGFloat(0.5),
+ stages: [25.0, 50.0, 75.0])
}
diff --git a/Map/Presentation/Base Components/MapRender/MapVertices.swift b/Map/Presentation/Base Components/MapRender/MapVertices.swift
index 74cac6d..5bc0a96 100644
--- a/Map/Presentation/Base Components/MapRender/MapVertices.swift
+++ b/Map/Presentation/Base Components/MapRender/MapVertices.swift
@@ -7,18 +7,29 @@ struct MapVertices: View {
let vertices: [Vertex]
let padding = CGFloat(5.0)
+ var onDragVertex: (Vertex, CGFloat, CGFloat) -> Void = { _, _, _ in }
+
var body: some View {
ZStack(alignment: .topLeading) {
ForEach(vertices, id: \.id) { vertex in
- getVertexShape(vertex).fill(Color.map.vertexColor)
- Text(vertex.label.replacingOccurrences(of: "\\n", with: "\n")).font(.theme.vertexLabel)
+ ZStack(alignment: .topLeading) {
+ getVertexShape(vertex).fill(Color.map.vertexColor)
+ Text(vertex.label.replacingOccurrences(of: "\\n", with: "\n")).font(.theme.vertexLabel)
.foregroundColor(.map.labelColor)
.shadow(color: .white, radius: 0, x: -0.5, y: -0.5)
.shadow(color: .white, radius: 0, x: 0.5, y: 0.5)
.offset(
- CGSize(
- width: w(vertex.position.x) + vertexSize.width + padding,
- height: h(vertex.position.y) + 7.0))
+ CGSize(
+ width: w(vertex.position.x) + vertexSize.width + padding,
+ height: 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)
+ }
+ )
}
}
}
@@ -78,15 +89,13 @@ struct MapVertices: View {
}
}
-struct MapVertices_Previews: PreviewProvider {
- static var previews: some View {
- MapVertices(
- mapSize: CGSize(width: 400.0, height: 400.0), vertexSize: CGSize(width: 25.0, height: 25.0),
- vertices: [
- Vertex(id: 0, label: "A Circle", position: CGPoint(x: 50.0, y: 50.0)),
- Vertex(id: 1, label: "A Square", position: CGPoint(x: 10.0, y: 20.0), shape: .square),
- Vertex(id: 2, label: "A triangle", position: CGPoint(x: 25, y: 32.0), shape: .triangle),
- Vertex(id: 3, label: "An X", position: CGPoint(x: 70.0, y: 70.0), shape: .x),
- ])
- }
+#Preview {
+ MapVertices(
+ mapSize: CGSize(width: 400.0, height: 400.0), vertexSize: CGSize(width: 25.0, height: 25.0),
+ vertices: [
+ Vertex(id: 0, label: "A Circle", position: CGPoint(x: 50.0, y: 50.0)),
+ Vertex(id: 1, label: "A Square", position: CGPoint(x: 10.0, y: 20.0), shape: .square),
+ Vertex(id: 2, label: "A triangle", position: CGPoint(x: 25, y: 32.0), shape: .triangle),
+ Vertex(id: 3, label: "An X", position: CGPoint(x: 70.0, y: 70.0), shape: .x),
+ ])
}