diff --git a/Symbolic.xcodeproj/project.pbxproj b/Symbolic.xcodeproj/project.pbxproj index 7082ad5a5d..84e158dee0 100644 --- a/Symbolic.xcodeproj/project.pbxproj +++ b/Symbolic.xcodeproj/project.pbxproj @@ -22,6 +22,8 @@ D83970EB28B1343C00282EE8 /* PreviewToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83970EA28B1343C00282EE8 /* PreviewToolbar.swift */; }; D86B0ECF291BEF7400352367 /* IconDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = D86B0ECE291BEF7400352367 /* IconDocument.swift */; }; D86B0ED1291BEFC100352367 /* UTType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D86B0ED0291BEFC100352367 /* UTType.swift */; }; + D8B61308293BB81100F29E0C /* AboutCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B61307293BB81100F29E0C /* AboutCommands.swift */; }; + D8B6130A293BB98100F29E0C /* ApplicationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B61309293BB98100F29E0C /* ApplicationModel.swift */; }; D8CD4A7E28AC35C300D57F34 /* SymbolicApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8CD4A7D28AC35C300D57F34 /* SymbolicApp.swift */; }; D8CD4A8028AC35C300D57F34 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8CD4A7F28AC35C300D57F34 /* ContentView.swift */; }; D8CD4A8228AC35C600D57F34 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D8CD4A8128AC35C600D57F34 /* Assets.xcassets */; }; @@ -71,6 +73,8 @@ D83970EA28B1343C00282EE8 /* PreviewToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewToolbar.swift; sourceTree = ""; }; D86B0ECE291BEF7400352367 /* IconDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconDocument.swift; sourceTree = ""; }; D86B0ED0291BEFC100352367 /* UTType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTType.swift; sourceTree = ""; }; + D8B61307293BB81100F29E0C /* AboutCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutCommands.swift; sourceTree = ""; }; + D8B61309293BB98100F29E0C /* ApplicationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationModel.swift; sourceTree = ""; }; D8CD4A7A28AC35C300D57F34 /* Symbolic.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Symbolic.app; sourceTree = BUILT_PRODUCTS_DIR; }; D8CD4A7D28AC35C300D57F34 /* SymbolicApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SymbolicApp.swift; sourceTree = ""; }; D8CD4A7F28AC35C300D57F34 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -131,6 +135,7 @@ D821B9E528ACDBC300504AA4 /* Models */ = { isa = PBXGroup; children = ( + D8B61309293BB98100F29E0C /* ApplicationModel.swift */, D821B9E728ACDBE000504AA4 /* Icon.swift */, D86B0ECE291BEF7400352367 /* IconDocument.swift */, D83970E828B1340900282EE8 /* PreviewType.swift */, @@ -167,6 +172,14 @@ path = "New Group"; sourceTree = ""; }; + D8B61306293BB7FF00F29E0C /* Commands */ = { + isa = PBXGroup; + children = ( + D8B61307293BB81100F29E0C /* AboutCommands.swift */, + ); + path = Commands; + sourceTree = ""; + }; D8CD4A7128AC35C300D57F34 = { isa = PBXGroup; children = ( @@ -192,15 +205,16 @@ D8CD4A7C28AC35C300D57F34 /* Symbolic */ = { isa = PBXGroup; children = ( - D82B24992915D8330093B073 /* New Group */, D8CD4A8628AC35C600D57F34 /* Symbolic.entitlements */, D83970E328B0B61700282EE8 /* Info.plist */, D8CD4A7D28AC35C300D57F34 /* SymbolicApp.swift */, D8CD4A8128AC35C600D57F34 /* Assets.xcassets */, + D8B61306293BB7FF00F29E0C /* Commands */, D8D9731228ACFBFA006CBF15 /* Environment */, D821B9DE28ACDB5500504AA4 /* Extensions */, D8F99EC128B13946007C3868 /* Licenses */, D821B9E528ACDBC300504AA4 /* Models */, + D82B24992915D8330093B073 /* New Group */, D8CD4A8328AC35C600D57F34 /* Preview Content */, D8D9730F28ACF8BA006CBF15 /* Toolbars */, D821B9EF28ACF0A900504AA4 /* Utilities */, @@ -413,6 +427,7 @@ D821B9E828ACDBE000504AA4 /* Icon.swift in Sources */, D821B9EC28ACDC2600504AA4 /* IconCorners.swift in Sources */, D821B9EE28ACDC6F00504AA4 /* SymbolPicker.swift in Sources */, + D8B61308293BB81100F29E0C /* AboutCommands.swift in Sources */, D8F6317428AC7D7A00DFEED0 /* SFSymbols.swift in Sources */, D83970E928B1340900282EE8 /* PreviewType.swift in Sources */, D83970E528B11F5200282EE8 /* SymbolicError.swift in Sources */, @@ -427,6 +442,7 @@ D821B9E028ACDB6000504AA4 /* View.swift in Sources */, D83970EB28B1343C00282EE8 /* PreviewToolbar.swift in Sources */, D8CD4A7E28AC35C300D57F34 /* SymbolicApp.swift in Sources */, + D8B6130A293BB98100F29E0C /* ApplicationModel.swift in Sources */, D86B0ECF291BEF7400352367 /* IconDocument.swift in Sources */, D821B9E228ACDB8500504AA4 /* NSColor.swift in Sources */, D8F6317628AC85C600DFEED0 /* SymbolPickerModel.swift in Sources */, diff --git a/Symbolic/Commands/AboutCommands.swift b/Symbolic/Commands/AboutCommands.swift new file mode 100644 index 0000000000..81a63dce1d --- /dev/null +++ b/Symbolic/Commands/AboutCommands.swift @@ -0,0 +1,43 @@ +// Copyright (c) 2022 InSeven Limited +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import SwiftUI + +struct AboutCommands: Commands { + + let applicationModel: ApplicationModel + + init(applicationModel: ApplicationModel) { + self.applicationModel = applicationModel + } + + var body: some Commands { + + CommandGroup(replacing: .appInfo) { + Button("About \(Bundle.main.preferredName ?? "")") { + DispatchQueue.main.async { + applicationModel.showAbout() + } + } + } + + } + +} diff --git a/Symbolic/Models/ApplicationModel.swift b/Symbolic/Models/ApplicationModel.swift new file mode 100644 index 0000000000..246bd1f52c --- /dev/null +++ b/Symbolic/Models/ApplicationModel.swift @@ -0,0 +1,53 @@ +// Copyright (c) 2022 InSeven Limited +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import SwiftUI + +import Diligence + +class ApplicationModel: ObservableObject { + + @MainActor private lazy var aboutWindow: NSWindow = { + return NSWindow(repository: "inseven/symbolic", copyright: "Copyright © 2022 Jason Morley") { + Action("GitHub", url: URL(string: "https://github.com/inseven/symbolic")!) + Action("InSeven Limited", url: URL(string: "https://inseven.co.uk")!) + } acknowledgements: { + Acknowledgements("Developers") { + Credit("Jason Morley", url: URL(string: "https://jbmorley.co.uk")) + } + Acknowledgements("Thanks") { + Credit("Sarah Barbour") + Credit("Michael Dales") + } + } licenses: { + License("Symbolic", author: "InSeven Limited", filename: "symbolic-license") + } + }() + + @MainActor func showAbout() { + dispatchPrecondition(condition: .onQueue(.main)) + NSApplication.shared.activate(ignoringOtherApps: true) + if !aboutWindow.isVisible { + aboutWindow.center() + } + aboutWindow.makeKeyAndOrderFront(nil) + } + +} diff --git a/Symbolic/SymbolicApp.swift b/Symbolic/SymbolicApp.swift index 5124ab8e09..ff87f7a367 100644 --- a/Symbolic/SymbolicApp.swift +++ b/Symbolic/SymbolicApp.swift @@ -20,31 +20,21 @@ import SwiftUI -import Diligence - @main struct SymbolicApp: App { + @StateObject var applicationModel = ApplicationModel() + var body: some Scene { DocumentGroup { IconDocument() } editor: { configuration in ContentView() + .environmentObject(applicationModel) } - - About(repository: "inseven/symbolic", copyright: "Copyright © 2022 Jason Morley") { - Action("GitHub", url: URL(string: "https://github.com/inseven/symbolic")!) - } acknowledgements: { - Acknowledgements("Developers") { - Credit("Jason Morley", url: URL(string: "https://jbmorley.co.uk")) - } - Acknowledgements("Thanks") { - Credit("Sarah Barbour") - Credit("Michael Dales") - } - } licenses: { - License("Symbolic", author: "InSeven Limited", filename: "symbolic-license") + .commands { + AboutCommands(applicationModel: applicationModel) } } diff --git a/diligence b/diligence index ee423170aa..792942c16d 160000 --- a/diligence +++ b/diligence @@ -1 +1 @@ -Subproject commit ee423170aaac7fe66b2818b86ee7166238920eda +Subproject commit 792942c16dbfb65cf3ab710b61d6914dafaebb7d