aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Beltran del Rio <git@r.bdr.sh>2025-09-16 12:01:07 +0200
committerRuben Beltran del Rio <git@r.bdr.sh>2025-09-16 12:01:07 +0200
commitd3e21e6050fd8cfde6ff7c68d9f8dfedf7b6301f (patch)
tree3e9d76f8f4be7febedbd1dac01f1adc1c4c1b7db
parent45e5a80ae378a72720114641c39148c199c6332d (diff)
Add glass
-rw-r--r--Config.xcconfig (renamed from Shared/Config.xcconfig)0
-rw-r--r--Map.xcodeproj/project.pbxproj64
-rw-r--r--Map.xcodeproj/xcshareddata/xcschemes/QuickLook.xcscheme4
-rw-r--r--Map/Presentation/Base Components/EvolutionPicker/EvolutionPicker.swift6
-rw-r--r--Map/Presentation/Base Components/EvolutionPicker/EvolutionPickerMenu.swift9
-rw-r--r--Map/Presentation/Base Components/EvolutionPicker/GlassEvolutionPicker.swift77
-rw-r--r--Map/Presentation/Base Components/MapTextEditor/HoverView.swift1
-rw-r--r--Map/Presentation/Commands/MapCommands.swift11
-rw-r--r--Map/Presentation/Complex Components/MapRender/MapRenderView.swift12
-rw-r--r--Map/Presentation/MapEditor.swift86
-rw-r--r--Map/Presentation/Preferences/TemplatesPreferencesView.swift2
-rw-r--r--Map/Presentation/Theme/Dimensions.swift18
12 files changed, 208 insertions, 82 deletions
diff --git a/Shared/Config.xcconfig b/Config.xcconfig
index 732bbea..732bbea 100644
--- a/Shared/Config.xcconfig
+++ b/Config.xcconfig
diff --git a/Map.xcodeproj/project.pbxproj b/Map.xcodeproj/project.pbxproj
index 130c91c..bc7c8f7 100644
--- a/Map.xcodeproj/project.pbxproj
+++ b/Map.xcodeproj/project.pbxproj
@@ -11,7 +11,7 @@
B5012E7F2C97315800AC4D68 /* ConcaveHull in Frameworks */ = {isa = PBXBuildFile; productRef = B5012E7E2C97315800AC4D68 /* ConcaveHull */; };
B51A45F52C982FAE00870ED5 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = B51A45F42C982FAE00870ED5 /* Sparkle */; };
B5282B052E210D4500C62006 /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5282B042E210D4400C62006 /* Quartz.framework */; };
- B5282B122E210D4500C62006 /* QuickLook.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = B5282B022E210D4400C62006 /* QuickLook.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
+ B5282B122E210D4500C62006 /* MapQuickLook.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = B5282B022E210D4400C62006 /* MapQuickLook.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
B5282B3D2E21109C00C62006 /* Patterns in Frameworks */ = {isa = PBXBuildFile; productRef = B5282B3C2E21109C00C62006 /* Patterns */; };
B5282B3F2E21109C00C62006 /* ConcaveHull in Frameworks */ = {isa = PBXBuildFile; productRef = B5282B3E2E21109C00C62006 /* ConcaveHull */; };
/* End PBXBuildFile section */
@@ -47,7 +47,7 @@
dstPath = "";
dstSubfolderSpec = 13;
files = (
- B5282B122E210D4500C62006 /* QuickLook.appex in Embed Foundation Extensions */,
+ B5282B122E210D4500C62006 /* MapQuickLook.appex in Embed Foundation Extensions */,
);
name = "Embed Foundation Extensions";
runOnlyForDeploymentPostprocessing = 0;
@@ -75,8 +75,9 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
- B5282B022E210D4400C62006 /* QuickLook.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = QuickLook.appex; sourceTree = BUILT_PRODUCTS_DIR; };
+ B5282B022E210D4400C62006 /* MapQuickLook.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MapQuickLook.appex; sourceTree = BUILT_PRODUCTS_DIR; };
B5282B042E210D4400C62006 /* Quartz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quartz.framework; path = System/Library/Frameworks/Quartz.framework; sourceTree = SDKROOT; };
+ B544FA1C2E66368D00E44DD7 /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = "<group>"; };
B545870C2C961E9C0067B788 /* Map.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Map.app; sourceTree = BUILT_PRODUCTS_DIR; };
B54587202C961E9E0067B788 /* MapTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MapTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
B545872A2C961E9E0067B788 /* MapUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MapUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -88,7 +89,7 @@
membershipExceptions = (
Info.plist,
);
- target = B5282B012E210D4400C62006 /* QuickLook */;
+ target = B5282B012E210D4400C62006 /* MapQuickLook */;
};
B5282B1B2E210D9F00C62006 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
@@ -129,21 +130,7 @@
"Presentation/Theme/NSColor+theme.swift",
"Presentation/Theme/NSFont+theme.swift",
);
- target = B5282B012E210D4400C62006 /* QuickLook */;
- };
- B564290B2E211EE400B1EE8B /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
- isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
- membershipExceptions = (
- Config.xcconfig,
- );
- target = B545870B2C961E9C0067B788 /* Map */;
- };
- B564290C2E211EE400B1EE8B /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
- isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
- membershipExceptions = (
- Config.xcconfig,
- );
- target = B5282B012E210D4400C62006 /* QuickLook */;
+ target = B5282B012E210D4400C62006 /* MapQuickLook */;
};
B59830752E17E7C700F5FBF6 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
@@ -180,7 +167,7 @@
/* Begin PBXFileSystemSynchronizedRootGroup section */
B5282B062E210D4500C62006 /* QuickLook */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (B5282B162E210D4500C62006 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = QuickLook; sourceTree = "<group>"; };
- B56429052E211C6900B1EE8B /* Shared */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (B564290B2E211EE400B1EE8B /* PBXFileSystemSynchronizedBuildFileExceptionSet */, B564290C2E211EE400B1EE8B /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = Shared; sourceTree = "<group>"; };
+ B56429052E211C6900B1EE8B /* Shared */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Shared; sourceTree = "<group>"; };
B598304E2E17E7C700F5FBF6 /* Map */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (B59830752E17E7C700F5FBF6 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, B5DF1E3F2E1868E8003477B5 /* PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet */, B5282B1B2E210D9F00C62006 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, B5282B492E21124E00C62006 /* PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = Map; sourceTree = "<group>"; };
B59830772E17E7CC00F5FBF6 /* MapTests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = MapTests; sourceTree = "<group>"; };
B598307C2E17E7D600F5FBF6 /* MapUITests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = MapUITests; sourceTree = "<group>"; };
@@ -236,6 +223,7 @@
isa = PBXGroup;
children = (
B56429052E211C6900B1EE8B /* Shared */,
+ B544FA1C2E66368D00E44DD7 /* Config.xcconfig */,
B598304E2E17E7C700F5FBF6 /* Map */,
B59830772E17E7CC00F5FBF6 /* MapTests */,
B598307C2E17E7D600F5FBF6 /* MapUITests */,
@@ -251,7 +239,7 @@
B545870C2C961E9C0067B788 /* Map.app */,
B54587202C961E9E0067B788 /* MapTests.xctest */,
B545872A2C961E9E0067B788 /* MapUITests.xctest */,
- B5282B022E210D4400C62006 /* QuickLook.appex */,
+ B5282B022E210D4400C62006 /* MapQuickLook.appex */,
);
name = Products;
sourceTree = "<group>";
@@ -259,9 +247,9 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
- B5282B012E210D4400C62006 /* QuickLook */ = {
+ B5282B012E210D4400C62006 /* MapQuickLook */ = {
isa = PBXNativeTarget;
- buildConfigurationList = B5282B132E210D4500C62006 /* Build configuration list for PBXNativeTarget "QuickLook" */;
+ buildConfigurationList = B5282B132E210D4500C62006 /* Build configuration list for PBXNativeTarget "MapQuickLook" */;
buildPhases = (
B5282AFE2E210D4400C62006 /* Sources */,
B5282AFF2E210D4400C62006 /* Frameworks */,
@@ -276,13 +264,13 @@
B5282B062E210D4500C62006 /* QuickLook */,
B56429052E211C6900B1EE8B /* Shared */,
);
- name = QuickLook;
+ name = MapQuickLook;
packageProductDependencies = (
B5282B3C2E21109C00C62006 /* Patterns */,
B5282B3E2E21109C00C62006 /* ConcaveHull */,
);
productName = QuickLook;
- productReference = B5282B022E210D4400C62006 /* QuickLook.appex */;
+ productReference = B5282B022E210D4400C62006 /* MapQuickLook.appex */;
productType = "com.apple.product-type.app-extension";
};
B545870B2C961E9C0067B788 /* Map */ = {
@@ -403,7 +391,7 @@
B545870B2C961E9C0067B788 /* Map */,
B545871F2C961E9E0067B788 /* MapTests */,
B54587292C961E9E0067B788 /* MapUITests */,
- B5282B012E210D4400C62006 /* QuickLook */,
+ B5282B012E210D4400C62006 /* MapQuickLook */,
);
};
/* End PBXProject section */
@@ -473,7 +461,7 @@
/* Begin PBXTargetDependency section */
B5282B112E210D4500C62006 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
- target = B5282B012E210D4400C62006 /* QuickLook */;
+ target = B5282B012E210D4400C62006 /* MapQuickLook */;
targetProxy = B5282B102E210D4500C62006 /* PBXContainerItemProxy */;
};
B54587222C961E9E0067B788 /* PBXTargetDependency */ = {
@@ -491,8 +479,7 @@
/* Begin XCBuildConfiguration section */
B5282B142E210D4500C62006 /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReferenceAnchor = B56429052E211C6900B1EE8B /* Shared */;
- baseConfigurationReferenceRelativePath = Config.xcconfig;
+ baseConfigurationReference = B544FA1C2E66368D00E44DD7 /* Config.xcconfig */;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = QuickLook/QuickLook.entitlements;
CODE_SIGN_STYLE = Automatic;
@@ -500,7 +487,7 @@
ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = QuickLook/Info.plist;
- INFOPLIST_KEY_CFBundleDisplayName = QuickLook;
+ INFOPLIST_KEY_CFBundleDisplayName = "Map QuickLook";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@@ -520,8 +507,7 @@
};
B5282B152E210D4500C62006 /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReferenceAnchor = B56429052E211C6900B1EE8B /* Shared */;
- baseConfigurationReferenceRelativePath = Config.xcconfig;
+ baseConfigurationReference = B544FA1C2E66368D00E44DD7 /* Config.xcconfig */;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = QuickLook/QuickLook.entitlements;
CODE_SIGN_STYLE = Automatic;
@@ -529,7 +515,7 @@
ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = QuickLook/Info.plist;
- INFOPLIST_KEY_CFBundleDisplayName = QuickLook;
+ INFOPLIST_KEY_CFBundleDisplayName = "Map QuickLook";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@@ -673,8 +659,7 @@
};
B54587352C961E9E0067B788 /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReferenceAnchor = B56429052E211C6900B1EE8B /* Shared */;
- baseConfigurationReferenceRelativePath = Config.xcconfig;
+ baseConfigurationReference = B544FA1C2E66368D00E44DD7 /* Config.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
@@ -694,7 +679,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
- MACOSX_DEPLOYMENT_TARGET = 14.0;
+ MACOSX_DEPLOYMENT_TARGET = 14;
MARKETING_VERSION = 4.1.1;
PRODUCT_BUNDLE_IDENTIFIER = systems.tranquil.Map;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -707,8 +692,7 @@
};
B54587362C961E9E0067B788 /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReferenceAnchor = B56429052E211C6900B1EE8B /* Shared */;
- baseConfigurationReferenceRelativePath = Config.xcconfig;
+ baseConfigurationReference = B544FA1C2E66368D00E44DD7 /* Config.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
@@ -728,7 +712,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
- MACOSX_DEPLOYMENT_TARGET = 14.0;
+ MACOSX_DEPLOYMENT_TARGET = 14;
MARKETING_VERSION = 4.1.1;
PRODUCT_BUNDLE_IDENTIFIER = systems.tranquil.Map;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -810,7 +794,7 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
- B5282B132E210D4500C62006 /* Build configuration list for PBXNativeTarget "QuickLook" */ = {
+ B5282B132E210D4500C62006 /* Build configuration list for PBXNativeTarget "MapQuickLook" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B5282B142E210D4500C62006 /* Debug */,
diff --git a/Map.xcodeproj/xcshareddata/xcschemes/QuickLook.xcscheme b/Map.xcodeproj/xcshareddata/xcschemes/QuickLook.xcscheme
index 900c4d5..ad7bc16 100644
--- a/Map.xcodeproj/xcshareddata/xcschemes/QuickLook.xcscheme
+++ b/Map.xcodeproj/xcshareddata/xcschemes/QuickLook.xcscheme
@@ -17,8 +17,8 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B5282B012E210D4400C62006"
- BuildableName = "QuickLook.appex"
- BlueprintName = "QuickLook"
+ BuildableName = "MapQuickLook.appex"
+ BlueprintName = "MapQuickLook"
ReferencedContainer = "container:Map.xcodeproj">
</BuildableReference>
</BuildActionEntry>
diff --git a/Map/Presentation/Base Components/EvolutionPicker/EvolutionPicker.swift b/Map/Presentation/Base Components/EvolutionPicker/EvolutionPicker.swift
index 5748e59..da67054 100644
--- a/Map/Presentation/Base Components/EvolutionPicker/EvolutionPicker.swift
+++ b/Map/Presentation/Base Components/EvolutionPicker/EvolutionPicker.swift
@@ -21,7 +21,7 @@ struct EvolutionPicker: View {
@FocusState var isFocused: Bool
@Binding var selectedEvolution: StageType
-
+
var body: some View {
Button(
@@ -60,9 +60,9 @@ struct EvolutionPicker: View {
)
.buttonStyle(.borderless)
.background(isShowingMenu ? Color.Theme.UI.foreground : Color.clear)
- .cornerRadius(4.0)
+ .cornerRadius(Dimensions.EvolutionPicker.radius)
.overlay(
- RoundedRectangle(cornerRadius: 4.0)
+ RoundedRectangle(cornerRadius: Dimensions.EvolutionPicker.radius)
.stroke(
isShowingMenu
? Color.Theme.UI.foreground : (isHovered ? Color.Theme.UI.foreground : Color.clear),
diff --git a/Map/Presentation/Base Components/EvolutionPicker/EvolutionPickerMenu.swift b/Map/Presentation/Base Components/EvolutionPicker/EvolutionPickerMenu.swift
index 73837a0..b9d76c6 100644
--- a/Map/Presentation/Base Components/EvolutionPicker/EvolutionPickerMenu.swift
+++ b/Map/Presentation/Base Components/EvolutionPicker/EvolutionPickerMenu.swift
@@ -5,7 +5,9 @@ struct EvolutionPickerMenu: View {
@Binding var selectedEvolution: StageType
private func select(_ stageType: StageType) {
- selectedEvolution = stageType
+ withAnimation {
+ selectedEvolution = stageType
+ }
}
var body: some View {
@@ -46,9 +48,8 @@ struct EvolutionPickerMenu: View {
}
}
}
- .padding(Dimensions.Spacing.coziest)
- .ignoresSafeArea()
-
+ .padding(.horizontal, Dimensions.Spacing.coziest)
+ .padding(.vertical, Dimensions.Spacing.regular)
}
}
diff --git a/Map/Presentation/Base Components/EvolutionPicker/GlassEvolutionPicker.swift b/Map/Presentation/Base Components/EvolutionPicker/GlassEvolutionPicker.swift
new file mode 100644
index 0000000..3b6f199
--- /dev/null
+++ b/Map/Presentation/Base Components/EvolutionPicker/GlassEvolutionPicker.swift
@@ -0,0 +1,77 @@
+// Copyright (C) 2024 Rubén Beltrán del Río
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see https://map.tranquil.systems.
+import SwiftUI
+
+@available(macOS 26, *)
+struct GlassEvolutionPicker: View {
+
+ @State var isShowingMenu = false
+ @FocusState var isFocused: Bool
+
+ @Binding var selectedEvolution: StageType
+
+ var body: some View {
+
+ Button(
+ action: {
+ isShowingMenu = !isShowingMenu
+ },
+ label: {
+ HStack(spacing: Dimensions.Spacing.loose) {
+ Text(Stage.title(selectedEvolution))
+ .font(.Theme.Body.emphasized)
+ ZStack {
+ Image(systemName: "chevron.up")
+ .resizable()
+ .scaledToFit()
+ .frame(
+ width: Dimensions.EvolutionPicker.controlSize,
+ height: Dimensions.EvolutionPicker.controlSize
+ )
+ .offset(CGSize(width: 0, height: -Dimensions.EvolutionPicker.controlSpacing))
+ Image(systemName: "chevron.down")
+ .resizable()
+ .scaledToFit()
+ .frame(
+ width: Dimensions.EvolutionPicker.controlSize,
+ height: Dimensions.EvolutionPicker.controlSize
+ )
+ .offset(CGSize(width: 0, height: Dimensions.EvolutionPicker.controlSpacing))
+ }
+ }
+ .padding(.horizontal, Dimensions.Spacing.regular)
+ .padding(.vertical, Dimensions.Spacing.cozy)
+ }
+ )
+ .buttonStyle(.glass)
+ .buttonBorderShape(.capsule)
+ .cornerRadius(Dimensions.EvolutionPicker.radius)
+ .popover(
+ isPresented: $isShowingMenu,
+ content: {
+ EvolutionPickerMenu(selectedEvolution: $selectedEvolution)
+ }
+ )
+ .onChange(of: selectedEvolution) {
+ isShowingMenu = false
+ }
+ .animation(.bouncy, value: selectedEvolution)
+ }
+}
+
+#Preview {
+ @Previewable @State var selectedEvolution: StageType = .behavior
+ EvolutionPicker(selectedEvolution: $selectedEvolution)
+}
diff --git a/Map/Presentation/Base Components/MapTextEditor/HoverView.swift b/Map/Presentation/Base Components/MapTextEditor/HoverView.swift
index bd6de42..eeccec3 100644
--- a/Map/Presentation/Base Components/MapTextEditor/HoverView.swift
+++ b/Map/Presentation/Base Components/MapTextEditor/HoverView.swift
@@ -39,7 +39,6 @@ class HoverView: NSView {
private func setupView(message: String, actionLabel: String) {
let box = NSBox()
box.boxType = .custom
- box.borderType = .lineBorder
box.cornerRadius = 8
box.borderColor = NSColor.separatorColor
box.fillColor = NSColor.controlBackgroundColor
diff --git a/Map/Presentation/Commands/MapCommands.swift b/Map/Presentation/Commands/MapCommands.swift
index a298956..fe21f57 100644
--- a/Map/Presentation/Commands/MapCommands.swift
+++ b/Map/Presentation/Commands/MapCommands.swift
@@ -62,6 +62,9 @@ struct MapCommands: Commands {
Button("commands.file.export") {
if let selectedEvolution, let document {
if let image = document.exportAsImage(withEvolution: selectedEvolution) {
+
+ // Capture image data to avoid sendability issues with NSImage
+ guard let tiffData = image.tiffRepresentation else { return }
let filename = url?.deletingPathExtension().lastPathComponent ?? "Untitled"
@@ -154,9 +157,11 @@ struct MapCommands: Commands {
savePanel.accessoryView = accessoryController.view
savePanel.begin { result in
- if result == .OK, let url = savePanel.url {
- if let tiffRepresentation = image.tiffRepresentation {
- let bitmapImage = NSBitmapImageRep(data: tiffRepresentation)
+ if result == .OK {
+ let bitmapImage = NSBitmapImageRep(data: tiffData)
+
+ Task { @MainActor in
+ guard let url = savePanel.url else { return }
let selectedFormat = formats[accessoryController.formatPopup.indexOfSelectedItem]
// Generate data based on selected format
diff --git a/Map/Presentation/Complex Components/MapRender/MapRenderView.swift b/Map/Presentation/Complex Components/MapRender/MapRenderView.swift
index fe98ace..ce95813 100644
--- a/Map/Presentation/Complex Components/MapRender/MapRenderView.swift
+++ b/Map/Presentation/Complex Components/MapRender/MapRenderView.swift
@@ -127,9 +127,15 @@ struct MapRenderView: View {
MapVertices(
mapSize: mapSize, vertexSize: vertexSize, vertices: parsedMap.vertices,
labelPositions: smartLabelPositions, onDragVertex: onDragVertex)
- MapGroups(mapSize: mapSize, vertexSize: vertexSize, groups: parsedMap.groups).drawingGroup(
- opaque: true
- ).opacity(0.1)
+ if #available(macOS 26.0, *) {
+ MapGroups(mapSize: mapSize, vertexSize: vertexSize, groups: parsedMap.groups)
+ .drawingGroup()
+ .opacity(0.1)
+ } else {
+ MapGroups(mapSize: mapSize, vertexSize: vertexSize, groups: parsedMap.groups).drawingGroup(
+ opaque: true
+ ).opacity(0.1)
+ }
MapNotes(
mapSize: mapSize, lineWidth: lineWidth, notes: parsedMap.notes)
}
diff --git a/Map/Presentation/MapEditor.swift b/Map/Presentation/MapEditor.swift
index f9a8dae..f5589e5 100644
--- a/Map/Presentation/MapEditor.swift
+++ b/Map/Presentation/MapEditor.swift
@@ -142,7 +142,9 @@ struct MapEditor: View {
.onChange(of: document.text) { _, _ in
buildVertexLineMap()
}
- }.background(Color.Theme.UI.background)
+ .padding(.bottom, Dimensions.MapEditor.additionalPadding)
+ }
+ .background(Color.Theme.UI.background)
.gesture(
MagnificationGesture()
.onChanged { value in
@@ -156,30 +158,64 @@ struct MapEditor: View {
)
}
}
- Divider()
- HStack {
- Spacer()
- Slider(
- value: $zoom, in: zoomRange, step: 0.1,
- label: {
- Text(formatZoom(zoom))
- .font(.Theme.SmallControl.regular)
- },
- minimumValueLabel: {
- Image(systemName: "minus.magnifyingglass")
- .font(.Theme.SmallControl.regular)
- .help("map_editor.zoom_out")
- },
- maximumValueLabel: {
- Image(systemName: "plus.magnifyingglass")
- .font(.Theme.SmallControl.regular)
- .help("map_editor.zoom_in")
- }
- ).frame(width: 200).padding(.trailing, 10.0)
- }.padding(4.0)
- }.toolbar {
- ToolbarItem(placement: .primaryAction) {
- EvolutionPicker(selectedEvolution: $selectedEvolution)
+
+ if #unavailable(macOS 26) {
+ Divider()
+ HStack {
+ Spacer()
+ Slider(
+ value: $zoom, in: zoomRange, step: 0.1,
+ label: {
+ Text(formatZoom(zoom))
+ .font(.Theme.SmallControl.regular)
+ },
+ minimumValueLabel: {
+ Image(systemName: "minus.magnifyingglass")
+ .font(.Theme.SmallControl.regular)
+ .help("map_editor.zoom_out")
+ },
+ maximumValueLabel: {
+ Image(systemName: "plus.magnifyingglass")
+ .font(.Theme.SmallControl.regular)
+ .help("map_editor.zoom_in")
+ }
+ ).frame(width: 200).padding(.trailing, 10.0)
+ }.padding(4.0)
+ }
+ }
+ .safeAreaInset(edge: .bottom, alignment: .trailing) {
+ if #available(macOS 26, *) {
+ HStack {
+ Slider(
+ value: $zoom, in: zoomRange, step: 0.1,
+ label: {
+ Text(formatZoom(zoom))
+ .font(.Theme.SmallControl.regular)
+ },
+ minimumValueLabel: {
+ Image(systemName: "minus.magnifyingglass")
+ .font(.Theme.SmallControl.regular)
+ .help("map_editor.zoom_out")
+ },
+ maximumValueLabel: {
+ Image(systemName: "plus.magnifyingglass")
+ .font(.Theme.SmallControl.regular)
+ .help("map_editor.zoom_in")
+ }
+ ).frame(width: 200)
+ .padding(Dimensions.Spacing.regular)
+ .glassEffect(.regular)
+ GlassEvolutionPicker(selectedEvolution: $selectedEvolution)
+ }
+ .padding(Dimensions.Spacing.regular)
+
+ }
+ }
+ .toolbar {
+ if #unavailable(macOS 26) {
+ ToolbarItem(placement: .primaryAction) {
+ EvolutionPicker(selectedEvolution: $selectedEvolution)
+ }
}
}
.focusedSceneValue(\.isSearching, $isSearching)
diff --git a/Map/Presentation/Preferences/TemplatesPreferencesView.swift b/Map/Presentation/Preferences/TemplatesPreferencesView.swift
index 51d1c5e..aab73ef 100644
--- a/Map/Presentation/Preferences/TemplatesPreferencesView.swift
+++ b/Map/Presentation/Preferences/TemplatesPreferencesView.swift
@@ -127,6 +127,7 @@ struct TemplatesPreferencesView: View {
HStack(spacing: Dimensions.Spacing.coziest) {
Button(action: { showingAddSheet = true }) {
Image(systemName: "plus")
+ .frame(width: 12, height: 12)
}
.keyboardShortcut("t", modifiers: [.command])
.help("preferences.templates.help.add")
@@ -135,6 +136,7 @@ struct TemplatesPreferencesView: View {
removeTemplate(selectedTemplate)
}) {
Image(systemName: "minus")
+ .frame(width: 12, height: 12)
}
.keyboardShortcut(.delete, modifiers: [.command])
.help("preferences.templates.help.remove \(selectedTemplate?.name ?? "")")
diff --git a/Map/Presentation/Theme/Dimensions.swift b/Map/Presentation/Theme/Dimensions.swift
index 26b4496..57bd8b8 100644
--- a/Map/Presentation/Theme/Dimensions.swift
+++ b/Map/Presentation/Theme/Dimensions.swift
@@ -79,11 +79,27 @@ struct Dimensions {
// MARK: - Assorted Controls
struct EvolutionPicker {
- static let radius = 8.0
+ static var radius: CGFloat {
+ if #available(macOS 26, *) {
+ return 12.0
+ } else {
+ return 4.0
+ }
+ }
static let controlSize = 8.0
static let controlSpacing = 3.0
}
+ struct MapEditor {
+ static var additionalPadding: CGFloat {
+ if #available(macOS 26, *) {
+ return 32.0
+ } else {
+ return 0.0
+ }
+ }
+ }
+
struct Preferences {
struct Window {