Skip to content

Commit 8885e1f

Browse files
Update new document experience on macOS
Displays a form similar to iOS and iPadOS that allows players to enter the version and seed before creating the file.
1 parent 0f0501b commit 8885e1f

File tree

5 files changed

+166
-108
lines changed

5 files changed

+166
-108
lines changed

MCMaps/Models/Document/CartographyMap.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import Foundation
99

1010
/// A representation of the basic Minecraft world map.
11-
struct CartographyMap: Codable, Hashable {
11+
struct CartographyMap: Codable, Hashable, Sendable {
1212
/// The seed used to generate the world in-game.
1313
var seed: Int64
1414

MCMaps/Resources/Alidade.docc/Articles/Changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ across Mac, iPhone, and iPad.
1515

1616
### Unreleased
1717

18+
- Updates the new document experience on macOS to match iOS and iPadOS
19+
with a new form that lets players enter the Minecraft version and seed
20+
before launching into a blank document.
1821
- Replaces the generic about screen with a more specialized and purpose
1922
built version on macOS.
2023
- Replaces the Minecraft version text field with a dropdown menu to

MCMaps/Views/DocumentLaunchView.swift renamed to MCMaps/Views/DocumentLaunchView/DocumentLaunchView+Desktop.swift

Lines changed: 47 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,13 @@
11
//
2-
// DocumentLaunchView.swift
2+
// DocumentLaunchView+Desktop.swift
33
// MCMaps
44
//
5-
// Created by Marquis Kurt on 01-03-2025.
5+
// Created by Marquis Kurt on 15-03-2025.
66
//
77

88
import SwiftUI
99

10-
#if os(iOS)
11-
/// A launch view that lets players create and open files easily.
12-
///
13-
/// This will generally be displayed when the app is first loaded.
14-
@available(iOS 18.0, *)
15-
struct DocumentLaunchView: Scene {
16-
@State private var creationContinuation: CheckedContinuation<CartographyMapFile?, any Error>?
17-
/// Whether the creation window should be visible.
18-
///
19-
/// Applicable to iOS and iPadOS.
20-
@Binding var displayCreationWindow: Bool
21-
22-
/// The proxy map used to create a file temporarily.
23-
///
24-
/// Applicable to iOS and iPadOS.
25-
@Binding var proxyMap: CartographyMap
26-
27-
var body: some Scene {
28-
DocumentGroupLaunchScene {
29-
NewDocumentButton("Create Map", for: CartographyMapFile.self) {
30-
try await withCheckedThrowingContinuation { continuation in
31-
self.creationContinuation = continuation
32-
self.displayCreationWindow = true
33-
}
34-
}
35-
.sheet(isPresented: $displayCreationWindow) {
36-
NavigationStack {
37-
MapCreatorForm(worldName: $proxyMap.name, mcVersion: $proxyMap.mcVersion, seed: $proxyMap.seed)
38-
.navigationTitle("Create Map")
39-
.toolbar {
40-
ToolbarItem(placement: .confirmationAction) {
41-
Button("Create") {
42-
creationContinuation?.resume(returning: .init(map: proxyMap))
43-
creationContinuation = nil
44-
displayCreationWindow = false
45-
}
46-
}
47-
48-
ToolbarItem(placement: .cancellationAction) {
49-
Button("Cancel") {
50-
creationContinuation?.resume(throwing: CocoaError(CocoaError.userCancelled))
51-
creationContinuation = nil
52-
displayCreationWindow = false
53-
}
54-
}
55-
}
56-
}
57-
}
58-
} background: {
59-
Image(.packMcmeta)
60-
.resizable()
61-
.aspectRatio(contentMode: .fill)
62-
}
63-
}
64-
}
65-
#else
10+
#if os(macOS)
6611
/// A launch view that lets players create and open files easily.
6712
///
6813
/// This will generally be displayed when the app is first loaded.
@@ -82,6 +27,7 @@ import SwiftUI
8227
@Environment(\.openDocument) private var openDocument
8328

8429
@State private var selectedFile: URL?
30+
@State private var displayCreationSheet = false
8531

8632
@ScaledMetric private var fileHeight = 36.0
8733
@ScaledMetric private var filePaddingH = 4.0
@@ -123,6 +69,25 @@ import SwiftUI
12369
.frame(width: 600, height: 400)
12470
.toolbarVisibility(.hidden, for: .windowToolbar)
12571
.containerBackground(.thinMaterial, for: .window)
72+
.sheet(isPresented: $displayCreationSheet) {
73+
NavigationStack {
74+
MapCreatorForm(worldName: $proxyMap.name, mcVersion: $proxyMap.mcVersion, seed: $proxyMap.seed)
75+
.navigationTitle("Create Map")
76+
.formStyle(.grouped)
77+
.toolbar {
78+
ToolbarItem(placement: .confirmationAction) {
79+
Button("Create") {
80+
createDocument()
81+
}
82+
}
83+
ToolbarItem(placement: .cancellationAction) {
84+
Button("Cancel", role: .cancel) {
85+
displayCreationSheet = false
86+
}
87+
}
88+
}
89+
}
90+
}
12691
}
12792
.windowStyle(.hiddenTitleBar)
12893
.windowResizability(.contentSize)
@@ -157,8 +122,7 @@ import SwiftUI
157122
Spacer()
158123
VStack(alignment: .leading) {
159124
Button {
160-
newDocument(contentType: .cartography)
161-
dismissWindow(id: "launch")
125+
displayCreationSheet.toggle()
162126
} label: {
163127
HStack {
164128
Label("Create a Map", systemImage: "document.badge.plus")
@@ -251,6 +215,19 @@ import SwiftUI
251215
}
252216
}
253217

218+
private func createDocument() {
219+
proxyMap.pins.append(CartographyMapPin(position: .zero, name: "Spawn Point"))
220+
proxyMap.recentLocations?.append(.zero)
221+
let newFile = CartographyMapFile(map: proxyMap)
222+
newDocument(newFile)
223+
displayCreationSheet = false
224+
Task {
225+
// NOTE(alicerunsonfedora): WTF is this bullshit? Can't you just dismiss normally you dirty fuck?
226+
try await Task.sleep(nanoseconds: 1000)
227+
dismissWindow(id: "launch")
228+
}
229+
}
230+
254231
private func openDocument(at url: URL) {
255232
Task {
256233
do {
@@ -289,40 +266,18 @@ import SwiftUI
289266
NSWorkspace.shared.activateFileViewerSelecting([url])
290267
}
291268
}
292-
#endif
293269

294-
private struct DocumentLaunchViewButtonModifier: ViewModifier {
295-
func body(content: Content) -> some View {
296-
content
297-
.frame(maxWidth: .infinity)
298-
.padding(.horizontal, 16)
299-
.padding(.vertical, 10)
300-
.background(Color.secondary.opacity(0.1))
301-
.controlSize(.extraLarge)
302-
.buttonStyle(.borderless)
303-
.bold()
304-
.clipped()
305-
.clipShape(.rect(cornerRadius: 10))
306-
}
307-
}
270+
#if DEBUG
271+
extension DocumentLaunchView {
272+
var testHooks: TestHooks { TestHooks(target: self) }
308273

309-
extension View {
310-
fileprivate func documentLaunchViewButtonStyle() -> some View {
311-
self.modifier(DocumentLaunchViewButtonModifier())
312-
}
313-
}
314-
315-
#if DEBUG
316-
extension DocumentLaunchView {
317-
var testHooks: TestHooks { TestHooks(target: self) }
274+
struct TestHooks {
275+
private let target: DocumentLaunchView
318276

319-
struct TestHooks {
320-
private let target: DocumentLaunchView
277+
fileprivate init(target: DocumentLaunchView) {
278+
self.target = target
279+
}
321280

322-
fileprivate init(target: DocumentLaunchView) {
323-
self.target = target
324-
}
325-
#if os(macOS)
326281
@available(macOS 15.0, *)
327282
func friendlyUrl(_ url: URL, for currentUser: String) -> String {
328283
target.friendlyUrl(url, for: currentUser)
@@ -337,12 +292,7 @@ extension View {
337292
func sanitize(url: URL) -> String {
338293
target.sanitize(url: url)
339294
}
340-
#else
341-
@available(iOS 18.0, *)
342-
var creationContinuation: CheckedContinuation<CartographyMapFile?, any Error>? {
343-
target.creationContinuation
344-
}
345-
#endif
295+
}
346296
}
347-
}
297+
#endif
348298
#endif
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
//
2+
// DocumentLaunchView+Mobile.swift
3+
// MCMaps
4+
//
5+
// Created by Marquis Kurt on 01-03-2025.
6+
//
7+
8+
import SwiftUI
9+
10+
#if os(iOS)
11+
/// A launch view that lets players create and open files easily.
12+
///
13+
/// This will generally be displayed when the app is first loaded.
14+
@available(iOS 18.0, *)
15+
struct DocumentLaunchView: Scene {
16+
@State private var creationContinuation: CheckedContinuation<CartographyMapFile?, any Error>?
17+
/// Whether the creation window should be visible.
18+
///
19+
/// Applicable to iOS and iPadOS.
20+
@Binding var displayCreationWindow: Bool
21+
22+
/// The proxy map used to create a file temporarily.
23+
///
24+
/// Applicable to iOS and iPadOS.
25+
@Binding var proxyMap: CartographyMap
26+
27+
var body: some Scene {
28+
DocumentGroupLaunchScene {
29+
NewDocumentButton("Create Map", for: CartographyMapFile.self) {
30+
try await withCheckedThrowingContinuation { continuation in
31+
self.creationContinuation = continuation
32+
self.displayCreationWindow = true
33+
}
34+
}
35+
.sheet(isPresented: $displayCreationWindow) {
36+
NavigationStack {
37+
MapCreatorForm(worldName: $proxyMap.name, mcVersion: $proxyMap.mcVersion, seed: $proxyMap.seed)
38+
.navigationTitle("Create Map")
39+
.toolbar {
40+
ToolbarItem(placement: .confirmationAction) {
41+
Button("Create") {
42+
creationContinuation?.resume(returning: .init(map: proxyMap))
43+
creationContinuation = nil
44+
displayCreationWindow = false
45+
}
46+
}
47+
48+
ToolbarItem(placement: .cancellationAction) {
49+
Button("Cancel") {
50+
creationContinuation?.resume(throwing: CocoaError(CocoaError.userCancelled))
51+
creationContinuation = nil
52+
displayCreationWindow = false
53+
}
54+
}
55+
}
56+
}
57+
}
58+
} background: {
59+
Image(.packMcmeta)
60+
.resizable()
61+
.aspectRatio(contentMode: .fill)
62+
}
63+
}
64+
}
65+
66+
#if DEBUG
67+
extension DocumentLaunchView {
68+
var testHooks: TestHooks { TestHooks(target: self) }
69+
70+
struct TestHooks {
71+
private let target: DocumentLaunchView
72+
73+
fileprivate init(target: DocumentLaunchView) {
74+
self.target = target
75+
}
76+
@available(iOS 18.0, *)
77+
var creationContinuation: CheckedContinuation<CartographyMapFile?, any Error>? {
78+
target.creationContinuation
79+
}
80+
}
81+
}
82+
#endif
83+
#endif
84+
85+
private struct DocumentLaunchViewButtonModifier: ViewModifier {
86+
func body(content: Content) -> some View {
87+
content
88+
.frame(maxWidth: .infinity)
89+
.padding(.horizontal, 16)
90+
.padding(.vertical, 10)
91+
.background(Color.secondary.opacity(0.1))
92+
.controlSize(.extraLarge)
93+
.buttonStyle(.borderless)
94+
.bold()
95+
.clipped()
96+
.clipShape(.rect(cornerRadius: 10))
97+
}
98+
}
99+
100+
extension View {
101+
func documentLaunchViewButtonStyle() -> some View {
102+
self.modifier(DocumentLaunchViewButtonModifier())
103+
}
104+
}

MCMaps/Views/Forms/MapCreatorForm.swift

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,6 @@ struct MapCreatorForm: View {
4343
}
4444
}
4545
TextField("Seed", text: $seedString)
46-
.onSubmit {
47-
if let realNumber = Int64(seedString) {
48-
seed = realNumber
49-
autoconvert = false
50-
} else {
51-
seed = Int64(seedString.hashValue)
52-
autoconvert = true
53-
}
54-
}
5546
} header: {
5647
Text("World Generation")
5748
} footer: {
@@ -65,12 +56,22 @@ struct MapCreatorForm: View {
6556
self.mcVersion = verString
6657
}
6758
}
59+
.onChange(of: seedString) { _, newValue in
60+
if let realNumber = Int64(newValue) {
61+
seed = realNumber
62+
autoconvert = false
63+
} else {
64+
let isEmptyField = newValue == ""
65+
seed = isEmptyField ? 0 : Int64(newValue.hashValue)
66+
autoconvert = !isEmptyField
67+
}
68+
}
6869
}
6970
.onAppear {
7071
version = MinecraftVersion(mcVersion)
7172
seedString = String(seed)
7273
#if DEBUG
73-
self.didAppear?(self)
74+
self.didAppear?(self)
7475
#endif
7576
}
7677
}

0 commit comments

Comments
 (0)