aboutsummaryrefslogtreecommitdiff
path: root/Map/Presentation/Complex Components/MapRender/MapRenderView.swift
blob: 3b979457f2694417237295f68750caa5b45459de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Copyright (C) 2024 Rubén Beltrán del Río

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program. If not, see https://map.tranquil.systems.
import Combine
import CoreData
import CoreGraphics
import SwiftUI

struct MapRenderView: View {

  @Binding var document: MapDocument
  @Binding var evolution: StageType
  @AppStorage("showMapBackground") var showMapBackground: Bool = true
  @AppStorage("useCustomFont") var useCustomFont: Bool = false
  @AppStorage("customFontName") var customFontName: String = "Helvetica"

  var stage: Stage {
    Stage.stages(evolution)
  }

  var parsedMap: ParsedMap {
    MapParser.parse(content: document.text)
  }

  let mapSize = Dimensions.Map.size
  let padding = Dimensions.Map.padding

  let lineWidth = CGFloat(0.5)
  let vertexSize = CGSize(width: 25.0, height: 25.0)

  var onDragVertex: (Vertex, CGFloat, CGFloat) -> Void = { _, _, _ in }

  var body: some View {
    ZStack(alignment: .topLeading) {

      Path { path in
        path.addRect(
          CGRect(
            x: -padding, y: -padding, width: mapSize.width + padding * 2,
            height: mapSize.height + padding * 4))
      }.fill(.white)

      // The order Matters. Think of this as layers.

      if showMapBackground {
        MapBackground(mapSize: mapSize, lineWidth: lineWidth, stages: parsedMap.stages)
      }
      MapAxes(
        mapSize: mapSize, lineWidth: lineWidth, evolution: stage, stages: parsedMap.stages)
      Group {
        MapStages(mapSize: mapSize, lineWidth: lineWidth, stages: parsedMap.stages)
        MapEdges(
          mapSize: mapSize, lineWidth: lineWidth, vertexSize: vertexSize, edges: parsedMap.edges)
        MapOpportunities(
          mapSize: mapSize, lineWidth: lineWidth, vertexSize: vertexSize,
          opportunities: parsedMap.opportunities)
        MapIntertias(mapSize: mapSize, vertexSize: vertexSize, inertias: parsedMap.inertias)
      }.mask {
        MapMask(
          mapSize: mapSize, vertexSize: vertexSize, vertices: parsedMap.vertices)
      }
      MapVertices(
        mapSize: mapSize, vertexSize: vertexSize, vertices: parsedMap.vertices,
        onDragVertex: onDragVertex)
      MapGroups(mapSize: mapSize, vertexSize: vertexSize, groups: parsedMap.groups).drawingGroup(
        opaque: true
      ).opacity(0.1)
      MapNotes(
        mapSize: mapSize, lineWidth: lineWidth, notes: parsedMap.notes)
    }
    .id("\(useCustomFont)-\(customFontName)")
    .offset(x: padding, y: padding).frame(
      width: mapSize.width + 2 * padding,
      height: mapSize.height + 2 * padding, alignment: .topLeading
    )
  }
}

#Preview {
  MapRenderView(
    document: Binding.constant(MapDocument(text: "")),
    evolution: Binding.constant(StageType.general)
  )
}