]> git.r.bdr.sh - rbdr/map/blob - Map/Presentation/Commands/MapCommands.swift
c04cb73f8c4b703098cd75bbff0a27aab9b4b91e
[rbdr/map] / Map / Presentation / Commands / MapCommands.swift
1 // Copyright (C) 2024 Rubén Beltrán del Río
2
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.
7
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.
12
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.
15 import SwiftUI
16
17 struct MapCommands: Commands {
18
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
25
26 var body: some Commands {
27
28 // File
29
30 CommandGroup(after: CommandGroupPlacement.saveItem) {
31 Divider()
32 Button("Export...") {
33 if let selectedEvolution, let document {
34 if let image = document.exportAsImage(withEvolution: selectedEvolution) {
35
36 let filename = url?.deletingPathExtension().lastPathComponent ?? "Untitled"
37
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: [:])
50 do {
51 try pngData?.write(to: url)
52 } catch {
53 return
54 }
55 }
56 }
57 }
58 }
59 }
60 }.keyboardShortcut(
61 "e", modifiers: EventModifiers([.command])
62 ).disabled(document == nil)
63 }
64
65 // Edit
66
67 CommandGroup(after: CommandGroupPlacement.pasteboard) {
68 Divider()
69 Button("Find...") {
70 withAnimation {
71 isSearching = isSearching != nil ? !isSearching! : true
72 }
73 }.keyboardShortcut(
74 "f", modifiers: EventModifiers([.command])
75 ).disabled(document == nil)
76 }
77
78 // View
79
80 CommandGroup(after: CommandGroupPlacement.toolbar) {
81 if viewStyle == .horizontal {
82 Button("Use Vertical Layout") {
83 viewStyle = .vertical
84 }.keyboardShortcut(
85 "l", modifiers: EventModifiers([.command])
86 ).disabled(document == nil)
87 } else {
88 Button("Use Horizontal Layout") {
89 viewStyle = .horizontal
90 }.keyboardShortcut(
91 "l", modifiers: EventModifiers([.command])
92 ).disabled(document == nil)
93 }
94 Divider()
95 Button("Zoom In") {
96 zoom = min(Constants.kMaxZoom, zoom + 0.1)
97 }.keyboardShortcut(
98 "+", modifiers: EventModifiers([.command])
99 ).disabled(document == nil)
100 Button("Zoom Out") {
101 zoom = max(Constants.kMinZoom, zoom - 0.1)
102 }.keyboardShortcut(
103 "-", modifiers: EventModifiers([.command])
104 ).disabled(document == nil)
105 Divider()
106 }
107
108 CommandGroup(replacing: CommandGroupPlacement.help) {
109 Button("Map Help") { NSWorkspace.shared.open(URL(string: "https://map.tranquil.systems")!) }
110 }
111 }
112 }