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
96
97
98
99
100
101
102
103
|
import Cocoa
import Foundation
import SwiftUI
struct AppState {
var selectedMap: Map? = nil
var mapBeingDeleted: Map? = nil
}
enum AppAction {
case selectMap(map: Map?)
case deleteMap(map: Map)
case exportMapAsImage(map: Map, evolution: StageType)
case exportMapAsText(map: Map)
}
func appStateReducer(state: inout AppState, action: AppAction) {
switch action {
case .selectMap(let map):
state.selectedMap = map
case .deleteMap(let map):
let context = PersistenceController.shared.container.viewContext
context.delete(map)
try? context.save()
case .exportMapAsImage(let map, let evolution):
let window = NSWindow(
contentRect: .init(
origin: .zero,
size: .init(
width: NSScreen.main!.frame.width,
height: NSScreen.main!.frame.height)),
styleMask: [.closable],
backing: .buffered,
defer: false)
window.title = map.title ?? "Untitled Map"
window.isOpaque = true
window.center()
window.isMovableByWindowBackground = true
window.makeKeyAndOrderFront(nil)
let renderView = MapRenderView(map: map, evolution: Stage.stages(evolution))
let view = NSHostingView(rootView: renderView)
window.contentView = view
let imageRepresentation = view.bitmapImageRepForCachingDisplay(in: view.bounds)!
view.cacheDisplay(in: view.bounds, to: imageRepresentation)
let image = NSImage(cgImage: imageRepresentation.cgImage!, size: view.bounds.size)
let dialog = NSSavePanel()
dialog.title = "Save Map"
dialog.showsResizeIndicator = false
dialog.canCreateDirectories = true
dialog.showsHiddenFiles = false
dialog.allowedFileTypes = ["png"]
dialog.nameFieldStringValue = map.title ?? "Untitled Map"
if dialog.runModal() == NSApplication.ModalResponse.OK {
let result = dialog.url
if result != nil {
image.writePNG(toURL: result!)
print("saved at \(result!)")
}
} else {
print("Cancel")
}
window.orderOut(nil)
case .exportMapAsText(let map):
let dialog = NSSavePanel()
dialog.title = "Save Map Text"
dialog.showsResizeIndicator = false
dialog.canCreateDirectories = true
dialog.showsHiddenFiles = false
dialog.allowedFileTypes = ["txt"]
dialog.nameFieldStringValue = map.title ?? "Untitled Map"
if let content = map.content {
if dialog.runModal() == NSApplication.ModalResponse.OK {
let result = dialog.url
if let result = result {
try? content.write(to: result, atomically: true, encoding: String.Encoding.utf8)
}
} else {
print("Cancel")
}
}
}
}
typealias AppStore = Store<AppState, AppAction>
|