1 // Copyright (C) 2024 Rubén Beltrán del Río
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program. If not, see https://map.tranquil.systems.
17 struct MapCommands: Commands {
19 @AppStorage("viewStyle") var viewStyle: ViewStyle = .horizontal
20 @AppStorage("zoom") var zoom = 1.0
21 @FocusedBinding(\.document) var document: MapDocument?
22 @FocusedValue(\.fileURL) var url: URL?
23 @FocusedBinding(\.selectedEvolution) var selectedEvolution: StageType?
24 @FocusedBinding(\.isSearching) var isSearching
26 var body: some Commands {
30 CommandGroup(after: CommandGroupPlacement.saveItem) {
33 if let selectedEvolution, let document {
34 if let image = document.exportAsImage(withEvolution: selectedEvolution) {
36 let filename = url?.deletingPathExtension().lastPathComponent ?? "Untitled"
38 let savePanel = NSSavePanel()
39 savePanel.allowedContentTypes = [.png]
40 savePanel.canCreateDirectories = true
41 savePanel.isExtensionHidden = false
42 savePanel.title = "Save \(filename) as image"
43 savePanel.message = "Choose a location to save the image"
44 savePanel.nameFieldStringValue = "\(filename).png"
45 savePanel.begin { result in
46 if result == .OK, let url = savePanel.url {
47 if let tiffRepresentation = image.tiffRepresentation {
48 let bitmapImage = NSBitmapImageRep(data: tiffRepresentation)
49 let pngData = bitmapImage?.representation(using: .png, properties: [:])
51 try pngData?.write(to: url)
61 "e", modifiers: EventModifiers([.command])
62 ).disabled(document == nil)
67 CommandGroup(after: CommandGroupPlacement.pasteboard) {
71 isSearching = isSearching != nil ? !isSearching! : true
74 "f", modifiers: EventModifiers([.command])
75 ).disabled(document == nil)
80 CommandGroup(after: CommandGroupPlacement.toolbar) {
81 if viewStyle == .horizontal {
82 Button("Use Vertical Layout") {
85 "l", modifiers: EventModifiers([.command])
86 ).disabled(document == nil)
88 Button("Use Horizontal Layout") {
89 viewStyle = .horizontal
91 "l", modifiers: EventModifiers([.command])
92 ).disabled(document == nil)
96 zoom = min(Constants.kMaxZoom, zoom + 0.1)
98 "+", modifiers: EventModifiers([.command])
99 ).disabled(document == nil)
101 zoom = max(Constants.kMinZoom, zoom - 0.1)
103 "-", modifiers: EventModifiers([.command])
104 ).disabled(document == nil)
108 CommandGroup(replacing: CommandGroupPlacement.help) {
109 Button("Map Help") { NSWorkspace.shared.open(URL(string: "https://map.tranquil.systems")!) }