diff --git a/Symbolic.xcodeproj/project.pbxproj b/Symbolic.xcodeproj/project.pbxproj index 37ef80b8f0..bab0fa5887 100644 --- a/Symbolic.xcodeproj/project.pbxproj +++ b/Symbolic.xcodeproj/project.pbxproj @@ -45,6 +45,7 @@ D8708190297C6121007CAE83 /* SavePanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D870818F297C6121007CAE83 /* SavePanel.swift */; }; D88661A3297AC893001E41DD /* InfoLabeledContentStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88661A2297AC893001E41DD /* InfoLabeledContentStyle.swift */; }; D88661A5297AD82A001E41DD /* ConditionalLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88661A4297AD82A001E41DD /* ConditionalLink.swift */; }; + D8A86B082CB5F2B60042AF5E /* ToolbarActionButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8A86B072CB5F2B40042AF5E /* ToolbarActionButtonStyle.swift */; }; D8B0B1F1296CD4AB00F907BE /* OffsetGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B0B1F0296CD4AB00F907BE /* OffsetGuide.swift */; }; D8B61308293BB81100F29E0C /* AboutCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B61307293BB81100F29E0C /* AboutCommands.swift */; }; D8B6130A293BB98100F29E0C /* ApplicationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B61309293BB98100F29E0C /* ApplicationModel.swift */; }; @@ -138,6 +139,7 @@ D88661A2297AC893001E41DD /* InfoLabeledContentStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoLabeledContentStyle.swift; sourceTree = ""; }; D88661A4297AD82A001E41DD /* ConditionalLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConditionalLink.swift; sourceTree = ""; }; D89A7404297C9BDE00F632ED /* SavePanel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SavePanel.swift; sourceTree = ""; }; + D8A86B072CB5F2B40042AF5E /* ToolbarActionButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolbarActionButtonStyle.swift; sourceTree = ""; }; D8B0B1F0296CD4AB00F907BE /* OffsetGuide.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OffsetGuide.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 = ""; }; @@ -300,6 +302,7 @@ D8B7677C298A728D00E99C6A /* LeadingToTrailingLabeledContentStyle.swift */, D8C99CF82993E5D800D85286 /* SidebarFormStyle.swift */, D8C99CFA2993E60300D85286 /* SidebarLabeledContentStyle.swift */, + D8A86B072CB5F2B40042AF5E /* ToolbarActionButtonStyle.swift */, ); path = Styles; sourceTree = ""; @@ -610,6 +613,7 @@ D83E84302CAE2F6600B59B1A /* Legal.swift in Sources */, D83970E528B11F5200282EE8 /* SymbolicError.swift in Sources */, D808A2152979918300763881 /* Variant.swift in Sources */, + D8A86B082CB5F2B60042AF5E /* ToolbarActionButtonStyle.swift in Sources */, D88661A5297AD82A001E41DD /* ConditionalLink.swift in Sources */, D86B0ED1291BEFC100352367 /* UTType.swift in Sources */, D8CD4A8028AC35C300D57F34 /* ContentView.swift in Sources */, diff --git a/Symbolic/Styles/ToolbarActionButtonStyle.swift b/Symbolic/Styles/ToolbarActionButtonStyle.swift new file mode 100644 index 0000000000..676fe26dbe --- /dev/null +++ b/Symbolic/Styles/ToolbarActionButtonStyle.swift @@ -0,0 +1,77 @@ +// Copyright (c) 2022-2024 Jason Morley +// +// 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 ToolbarActionButtonStyle: ButtonStyle { + + @State var isHovering: Bool = false + @Environment(\.colorScheme) var colorScheme + + struct LayoutMetrics { + static let buttonCornerRadius = 6.0 + static let buttonPadding = 6.0 + } + + func brightness(for configuration: Configuration) -> CGFloat { + switch colorScheme { + case .dark: + if configuration.isPressed { + return 0.2 + } else if isHovering { + return 0.1 + } else { + return 0.0 + } + default: + if configuration.isPressed { + return -0.2 + } else if isHovering { + return 0.1 + } else { + return 0.0 + } + } + } + + func makeBody(configuration: Configuration) -> some View { + configuration.label + .labelStyle(.titleOnly) + .padding(LayoutMetrics.buttonPadding) + .foregroundColor(.white) + .background(Color.accentColor + .brightness(brightness(for: configuration)) + .cornerRadius(LayoutMetrics.buttonCornerRadius)) + .onHover { isHovering in + withAnimation { + self.isHovering = isHovering + } + } + } + +} + +extension ButtonStyle where Self == ToolbarActionButtonStyle { + + static var toolbarAction: Self { + return .init() + } + +} diff --git a/Symbolic/Toolbars/ExportToolbar.swift b/Symbolic/Toolbars/ExportToolbar.swift index 8f549ed2ad..597fdf7068 100644 --- a/Symbolic/Toolbars/ExportToolbar.swift +++ b/Symbolic/Toolbars/ExportToolbar.swift @@ -38,12 +38,10 @@ struct ExportToolbar: CustomizableToolbarContent { sceneModel?.export() } } label: { - Text("Export") - .foregroundStyle(.white) + Label("Export", systemImage: "arrow.down.document") } - .background(Color.accentColor - .cornerRadius(LayoutMetrics.buttonCornerRadius)) .help("Export icons") + .buttonStyle(.toolbarAction) } }