diff options
| author | Ruben Beltran del Rio <git@r.bdr.sh> | 2024-09-16 11:10:32 +0200 |
|---|---|---|
| committer | Ruben Beltran del Rio <git@r.bdr.sh> | 2024-09-16 11:10:32 +0200 |
| commit | e2c37ac1dd2ad562e3d619d39b72a174a2212b67 (patch) | |
| tree | d4da2c0a12db0473eb4030014a92045eebe38834 /Map/Data | |
| parent | fdb4633d3e9158e457d57e820df6e1efb4df39c2 (diff) | |
Map 3 first commit: files, groups and layout
Diffstat (limited to 'Map/Data')
| -rw-r--r-- | Map/Data/AppState.swift | 103 | ||||
| -rw-r--r-- | Map/Data/MapDocument.swift | 42 | ||||
| -rw-r--r-- | Map/Data/Models/Map+parse.swift | 29 | ||||
| -rw-r--r-- | Map/Data/Persistence.swift | 42 | ||||
| -rw-r--r-- | Map/Data/Store.swift | 18 |
5 files changed, 42 insertions, 192 deletions
diff --git a/Map/Data/AppState.swift b/Map/Data/AppState.swift deleted file mode 100644 index d0d5670..0000000 --- a/Map/Data/AppState.swift +++ /dev/null @@ -1,103 +0,0 @@ -import Cocoa -import Foundation -import SwiftUI - -struct AppState { - var selectedEvolution: StageType = .general -} - -enum AppAction { - case selectEvolution(evolution: StageType) - case exportMapAsImage(map: Map) - case exportMapAsText(map: Map) - case deleteMap(map: Map) -} - -func appStateReducer(state: inout AppState, action: AppAction) { - - switch action { - - case .selectEvolution(let evolution): - state.selectedEvolution = evolution - - case .exportMapAsImage(let map): - 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( - content: Binding.constant(map.content ?? ""), - evolution: Binding.constant(state.selectedEvolution)) - - 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.allowedContentTypes = [.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.allowedContentTypes = [.text] - 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") - } - } - case .deleteMap(let map): - let context = PersistenceController.shared.container.viewContext - context.delete(map) - - try? context.save() - } -} - -typealias AppStore = Store<AppState, AppAction> diff --git a/Map/Data/MapDocument.swift b/Map/Data/MapDocument.swift new file mode 100644 index 0000000..9340684 --- /dev/null +++ b/Map/Data/MapDocument.swift @@ -0,0 +1,42 @@ +import SwiftUI +import UniformTypeIdentifiers + +extension UTType { + static var exampleText: UTType { + UTType(importedAs: "systems.tranquil.map.wmap") + } +} + +struct MapDocument: FileDocument { + var text: String + + init(text: String = "Hello, world!") { + self.text = text + } + + static var readableContentTypes: [UTType] { [.exampleText] } + + init(configuration: ReadConfiguration) throws { + guard let data = configuration.file.regularFileContents, + let string = String(data: data, encoding: .utf8) + else { + throw CocoaError(.fileReadCorruptFile) + } + text = string + } + + func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper { + let data = text.data(using: .utf8)! + return .init(regularFileWithContents: data) + } + + @MainActor + func exportAsImage(withEvolution selectedEvolution: StageType) -> NSImage? { + let renderView = MapRenderView( + document: .constant(self), + evolution: .constant(selectedEvolution)) + let renderer = ImageRenderer(content: renderView) + + return renderer.nsImage + } +} diff --git a/Map/Data/Models/Map+parse.swift b/Map/Data/Models/Map+parse.swift deleted file mode 100644 index 5181daf..0000000 --- a/Map/Data/Models/Map+parse.swift +++ /dev/null @@ -1,29 +0,0 @@ -extension Map { - static func parse(content: String) -> ParsedMap { - - let parsers = [ - AnyMapParserStrategy(NoteParserStrategy()), - AnyMapParserStrategy(VertexParserStrategy()), - AnyMapParserStrategy(EdgeParserStrategy()), - AnyMapParserStrategy(BlockerParserStrategy()), - AnyMapParserStrategy(OpportunityParserStrategy()), - AnyMapParserStrategy(StageParserStrategy()), - ] - let builder = MapBuilder() - - let lines = content.split(whereSeparator: \.isNewline) - - for (index, line) in lines.enumerated() { - for parser in parsers { - if parser.canHandle(line: String(line)) { - let (type, object) = parser.handle( - index: index, line: String(line), vertices: builder.vertices) - builder.addObjectToMap(type: type, object: object) - break - } - } - } - - return builder.build() - } -} diff --git a/Map/Data/Persistence.swift b/Map/Data/Persistence.swift deleted file mode 100644 index 1eb09e8..0000000 --- a/Map/Data/Persistence.swift +++ /dev/null @@ -1,42 +0,0 @@ -import CoreData - -struct PersistenceController { - static let shared = PersistenceController() - - static var preview: PersistenceController = { - let result = PersistenceController(inMemory: true) - let viewContext = result.container.viewContext - for _ in 0..<10 { - let newMap = Map(context: viewContext) - newMap.uuid = UUID() - newMap.createdAt = Date() - newMap.title = "Map \(newMap.createdAt!.format())" - newMap.content = "" - } - do { - try viewContext.save() - } catch { - let nsError = error as NSError - fatalError("Unresolved error \(nsError), \(nsError.userInfo)") - } - return result - }() - - let container: NSPersistentCloudKitContainer - - init(inMemory: Bool = false) { - container = NSPersistentCloudKitContainer(name: "Map") - - container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy - container.viewContext.automaticallyMergesChangesFromParent = true - - if inMemory { - container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") - } - container.loadPersistentStores(completionHandler: { (storeDescription, error) in - if let error = error as NSError? { - fatalError("Unresolved error \(error), \(error.userInfo)") - } - }) - } -} diff --git a/Map/Data/Store.swift b/Map/Data/Store.swift deleted file mode 100644 index 7860f33..0000000 --- a/Map/Data/Store.swift +++ /dev/null @@ -1,18 +0,0 @@ -import Foundation - -final class Store<State, Action>: ObservableObject { - @Published private(set) var state: State - - private let reducer: Reducer<State, Action> - - init(initialState: State, reducer: @escaping Reducer<State, Action>) { - self.state = initialState - self.reducer = reducer - } - - func send(_ action: Action) { - reducer(&state, action) - } -} - -typealias Reducer<State, Action> = (inout State, Action) -> Void |