aboutsummaryrefslogtreecommitdiff
path: root/Map/Presentation/Base Components
diff options
context:
space:
mode:
Diffstat (limited to 'Map/Presentation/Base Components')
-rw-r--r--Map/Presentation/Base Components/EvolutionPicker.swift30
-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
-rw-r--r--Map/Presentation/Base Components/MapTextEditor.swift89
11 files changed, 287 insertions, 138 deletions
diff --git a/Map/Presentation/Base Components/EvolutionPicker.swift b/Map/Presentation/Base Components/EvolutionPicker.swift
index c68e90c..c30798a 100644
--- a/Map/Presentation/Base Components/EvolutionPicker.swift
+++ b/Map/Presentation/Base Components/EvolutionPicker.swift
@@ -2,40 +2,30 @@ import SwiftUI
struct EvolutionPicker: View {
- @EnvironmentObject private var store: AppStore
-
- private var selectedEvolution: Binding<StageType> {
- Binding(
- get: { store.state.selectedEvolution },
- set: { evolution in
- store.send(.selectEvolution(evolution: evolution))
- }
- )
- }
+ @Binding var selectedEvolution: StageType
var body: some View {
- Picker("Evolution", selection: selectedEvolution) {
+ Picker("Evolution", selection: $selectedEvolution) {
ForEach(StageType.types) { stage in
- Text(Stage.title(stage)).tag(stage).padding(4.0)
+ Text(Stage.title(stage)).font(.theme.body).tag(stage).padding(4.0)
}
Divider()
ForEach(StageType.characteristics) { stage in
- Text(Stage.title(stage)).tag(stage).padding(4.0)
+ Text(Stage.title(stage)).font(.theme.body).tag(stage).padding(4.0).font(.theme.body)
}
Divider()
ForEach(StageType.properties) { stage in
- Text(Stage.title(stage)).tag(stage).padding(4.0)
+ Text(Stage.title(stage)).font(.theme.body).tag(stage).padding(4.0)
}
Divider()
ForEach(StageType.custom) { stage in
- Text(Stage.title(stage)).tag(stage).padding(4.0)
+ Text(Stage.title(stage)).font(.theme.body).tag(stage).padding(4.0)
}
- }.padding(.horizontal, 8.0).padding(.vertical, 4.0)
+ }.font(.theme.body).padding(.horizontal, 8.0).padding(.vertical, 4.0)
}
}
-struct EvolutionPicker_Previews: PreviewProvider {
- static var previews: some View {
- EvolutionPicker()
- }
+#Preview {
+ let selectedEvolution: StageType = .behavior
+ EvolutionPicker(selectedEvolution: .constant(selectedEvolution))
}
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),
+ ])
}
diff --git a/Map/Presentation/Base Components/MapTextEditor.swift b/Map/Presentation/Base Components/MapTextEditor.swift
index f3838a6..d7aa9f8 100644
--- a/Map/Presentation/Base Components/MapTextEditor.swift
+++ b/Map/Presentation/Base Components/MapTextEditor.swift
@@ -3,7 +3,7 @@ import SwiftUI
class MapTextEditorController: NSViewController {
- @Binding var text: String
+ @Binding var document: MapDocument
let onChange: () -> Void
private let vertexRegex = MapParsingPatterns.vertex
@@ -12,11 +12,12 @@ class MapTextEditorController: NSViewController {
private let opportunityRegex = MapParsingPatterns.opportunity
private let noteRegex = MapParsingPatterns.note
private let stageRegex = MapParsingPatterns.stage
+ private let groupRegex = MapParsingPatterns.group
private let changeDebouncer: Debouncer = Debouncer(seconds: 1)
- init(text: Binding<String>, onChange: @escaping () -> Void) {
- self._text = text
+ init(document: Binding<MapDocument>, onChange: @escaping () -> Void) {
+ self._document = document
self.onChange = onChange
super.init(nibName: nil, bundle: nil)
}
@@ -31,10 +32,11 @@ class MapTextEditorController: NSViewController {
scrollView.translatesAutoresizingMaskIntoConstraints = false
+ textView.backgroundColor = .ui.background
textView.allowsUndo = true
textView.delegate = self
textView.textStorage?.delegate = self
- textView.string = self.text
+ textView.string = self.document.text
textView.isEditable = true
textView.font = .monospacedSystemFont(ofSize: 16.0, weight: .regular)
self.view = scrollView
@@ -49,14 +51,13 @@ extension MapTextEditorController: NSTextViewDelegate {
func textDidChange(_ obj: Notification) {
if let textField = obj.object as? NSTextView {
- self.text = textField.string
-
-
- changeDebouncer.debounce {
- DispatchQueue.main.async {
- self.onChange()
- }
+ self.document.text = textField.string
+
+ changeDebouncer.debounce {
+ DispatchQueue.main.async {
+ self.onChange()
}
+ }
}
}
@@ -86,65 +87,91 @@ extension MapTextEditorController: NSTextStorageDelegate {
var matches = vertexRegex.matches(in: textStorage.string, options: [], range: range)
for match in matches {
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 1))
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.number], range: match.range(at: 2))
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.number], range: match.range(at: 3))
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.option], range: match.range(at: 4))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 1))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.number], range: match.range(at: 2))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.number], range: match.range(at: 3))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.option], range: match.range(at: 4))
}
matches = edgeRegex.matches(in: textStorage.string, options: [], range: range)
for match in matches {
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 1))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 1))
let arrowRange = match.range(at: 2)
textStorage.addAttributes(
[.foregroundColor: NSColor.syntax.symbol],
range: NSMakeRange(arrowRange.lowerBound - 1, arrowRange.length + 1))
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 3))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 3))
}
matches = opportunityRegex.matches(in: textStorage.string, options: [], range: range)
for match in matches {
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.option], range: match.range(at: 1))
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 2))
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.symbol], range: match.range(at: 3))
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.number], range: match.range(at: 4))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.option], range: match.range(at: 1))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 2))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.symbol], range: match.range(at: 3))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.number], range: match.range(at: 4))
}
matches = blockerRegex.matches(in: textStorage.string, options: [], range: range)
for match in matches {
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.option], range: match.range(at: 1))
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 2))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.option], range: match.range(at: 1))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 2))
}
-
+
matches = noteRegex.matches(in: textStorage.string, options: [], range: range)
for match in matches {
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.option], range: match.range(at: 1))
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.number], range: match.range(at: 2))
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.number], range: match.range(at: 3))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.option], range: match.range(at: 1))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.number], range: match.range(at: 2))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.number], range: match.range(at: 3))
}
matches = stageRegex.matches(in: textStorage.string, options: [], range: range)
for match in matches {
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.option], range: match.range(at: 1))
- textStorage.addAttributes([.foregroundColor: NSColor.syntax.number], range: match.range(at: 2))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.option], range: match.range(at: 1))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.number], range: match.range(at: 2))
+ }
+
+ matches = groupRegex.matches(in: textStorage.string, options: [], range: range)
+
+ for match in matches {
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.option], range: match.range(at: 1))
+ textStorage.addAttributes(
+ [.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 2))
}
}
}
struct MapTextEditor: NSViewControllerRepresentable {
- @Binding var text: String
+ @Binding var document: MapDocument
var onChange: () -> Void = {}
func makeNSViewController(
context: NSViewControllerRepresentableContext<MapTextEditor>
) -> MapTextEditorController {
- return MapTextEditorController(text: $text, onChange: onChange)
+ return MapTextEditorController(document: $document, onChange: onChange)
}
func updateNSViewController(