A collection of user interface components and drawing routines for building tasteful apps using AppKit.
appkit swift aqua ui mac

Scope the NSGraphicsContext calls

+264 -276
+8 -8
Sources/AquaKit/Drawers/AquaDrawerFrameView.swift
··· 46 46 override func draw(_ dirtyRect: NSRect) { 47 47 super.draw(dirtyRect) 48 48 49 - NSGraphicsContext.saveGraphicsState() 50 - let shadow = NSShadow() 51 - shadow.shadowColor = .black.withAlphaComponent(0.7) 52 - shadow.shadowBlurRadius = 5.0 53 - shadow.set() 49 + NSGraphicsContext.scope { 50 + let shadow = NSShadow() 51 + shadow.shadowColor = .black.withAlphaComponent(0.7) 52 + shadow.shadowBlurRadius = 5.0 53 + shadow.set() 54 54 55 - NSColor.controlColor.setStroke() 56 - strokePath.stroke() 57 - NSGraphicsContext.restoreGraphicsState() 55 + NSColor.controlColor.setStroke() 56 + strokePath.stroke() 57 + } 58 58 } 59 59 60 60 required init?(coder: NSCoder) { fatalError() }
+13
Sources/AquaKit/General Purpose/NSGraphicsContext+Scope.swift
··· 1 + // SPDX-FileCopyrightText: 2026 Jon Sterling 2 + // 3 + // SPDX-License-Identifier: MIT 4 + 5 + import AppKit 6 + 7 + extension NSGraphicsContext { 8 + public static func scope<Value>(_ body: () -> Value) -> Value { 9 + saveGraphicsState() 10 + defer { restoreGraphicsState() } 11 + return body() 12 + } 13 + }
+116 -137
Sources/AquaKit/Scroll Views/AquaScroller.swift
··· 142 142 143 143 let knobPath = NSBezierPath(roundedRect: knobRect, xRadius: radius, yRadius: radius) 144 144 145 - NSGraphicsContext.saveGraphicsState() 146 - 147 - do { 148 - NSGraphicsContext.saveGraphicsState() 145 + NSGraphicsContext.scope { 149 146 150 - let shadow = NSShadow() 151 - shadow.shadowColor = .black 152 - shadow.shadowBlurRadius = 2 153 - shadow.set() 147 + NSGraphicsContext.scope { 148 + let shadow = NSShadow() 149 + shadow.shadowColor = .black 150 + shadow.shadowBlurRadius = 2 151 + shadow.set() 154 152 155 - NSColor.black.withAlphaComponent(0.4).setStroke() 153 + NSColor.black.withAlphaComponent(0.4).setStroke() 156 154 157 - knobPath.stroke() 155 + knobPath.stroke() 158 156 159 - if isInKeyWindow { 160 - NSColor(patternImage: wavePatternImage).setFill() 161 - knobPath.fill() 157 + if isInKeyWindow { 158 + NSColor(patternImage: wavePatternImage).setFill() 159 + knobPath.fill() 160 + } 162 161 } 163 162 164 - NSGraphicsContext.restoreGraphicsState() 165 - } 166 - 167 - do { 168 - NSGraphicsContext.saveGraphicsState() 169 - knobPath.addClip() 163 + NSGraphicsContext.scope { 164 + knobPath.addClip() 170 165 171 - var baseColor: NSColor 172 - if let window, window.isKeyWindow { 173 - baseColor = NSColor.controlAccentColor.usingColorSpace(.displayP3)! 174 - if baseColor.isGrayscale { 175 - baseColor = NSColor.graphiteColor 166 + var baseColor: NSColor 167 + if let window, window.isKeyWindow { 168 + baseColor = NSColor.controlAccentColor.usingColorSpace(.displayP3)! 169 + if baseColor.isGrayscale { 170 + baseColor = NSColor.graphiteColor 171 + } else { 172 + baseColor = NSColor( 173 + calibratedHue: baseColor.hueComponent - 0.03, 174 + saturation: 0.8, 175 + brightness: 0.9, 176 + alpha: 1.0 177 + ) 178 + } 176 179 } else { 177 - baseColor = NSColor( 178 - calibratedHue: baseColor.hueComponent - 0.03, 179 - saturation: 0.8, 180 - brightness: 0.9, 181 - alpha: 1.0 182 - ) 180 + baseColor = NSColor.graphiteColor.highlight(withLevel: 0.5)! 183 181 } 184 - } else { 185 - baseColor = NSColor.graphiteColor.highlight(withLevel: 0.5)! 186 - } 187 182 188 - if effectiveAppearance.isDarkAqua { 189 - baseColor = baseColor.blended(withFraction: 0.3, of: .graphiteColor.shadow(withLevel: 0.8)!)! 190 - } 183 + if effectiveAppearance.isDarkAqua { 184 + baseColor = baseColor.blended(withFraction: 0.3, of: .graphiteColor.shadow(withLevel: 0.8)!)! 185 + } 191 186 192 - do { 193 - NSGraphicsContext.saveGraphicsState() 194 - NSGraphicsContext.current?.cgContext.setAlpha(0.9) 195 - baseColor.setFill() 196 - knobRect.fill() 197 - NSGraphicsContext.restoreGraphicsState() 198 - } 187 + NSGraphicsContext.scope { 188 + NSGraphicsContext.current?.cgContext.setAlpha(0.9) 189 + baseColor.setFill() 190 + knobRect.fill() 191 + } 199 192 200 - // shading at the ends of the knob 201 - if isInKeyWindow { 202 - let frontEdge: CGRectEdge = 203 - switch axis { 204 - case .vertical: .minYEdge 205 - case .horizontal: .minXEdge 206 - } 193 + // shading at the ends of the knob 194 + if isInKeyWindow { 195 + let frontEdge: CGRectEdge = 196 + switch axis { 197 + case .vertical: .minYEdge 198 + case .horizontal: .minXEdge 199 + } 207 200 208 - let backEdge: CGRectEdge = 209 - switch axis { 210 - case .vertical: .maxYEdge 211 - case .horizontal: .maxXEdge 212 - } 201 + let backEdge: CGRectEdge = 202 + switch axis { 203 + case .vertical: .maxYEdge 204 + case .horizontal: .maxXEdge 205 + } 213 206 214 - let distance = min(scrollerWidth / 1.5, knobRect.size[axis] / 3.0) 215 - let gradient = NSGradient(colors: [baseColor.shadow(withLevel: 0.6)!.withAlphaComponent(0.5), .clear]) 216 - let frontRect = knobRect.divided(atDistance: distance, from: frontEdge).slice 217 - let backRect = knobRect.divided(atDistance: distance, from: backEdge).slice 218 - gradient?.draw(in: frontRect, angle: axis.mainGradientAngle) 219 - gradient?.draw(in: backRect, angle: 180.0 + axis.mainGradientAngle) 220 - } 207 + let distance = min(scrollerWidth / 1.5, knobRect.size[axis] / 3.0) 208 + let gradient = NSGradient(colors: [baseColor.shadow(withLevel: 0.6)!.withAlphaComponent(0.5), .clear]) 209 + let frontRect = knobRect.divided(atDistance: distance, from: frontEdge).slice 210 + let backRect = knobRect.divided(atDistance: distance, from: backEdge).slice 211 + gradient?.draw(in: frontRect, angle: axis.mainGradientAngle) 212 + gradient?.draw(in: backRect, angle: 180.0 + axis.mainGradientAngle) 213 + } 221 214 222 - // shine highlight along leading cross edge 223 - do { 224 - NSGraphicsContext.saveGraphicsState() 215 + // shine highlight along leading cross edge 216 + NSGraphicsContext.scope { 217 + let shineGradient = NSGradient(colors: [ 218 + .white, 219 + .white.withAlphaComponent(isInKeyWindow ? 0.4 : 0.8) 220 + ])! 225 221 226 - let shineGradient = NSGradient(colors: [ 227 - .white, 228 - .white.withAlphaComponent(isInKeyWindow ? 0.4 : 0.8) 229 - ])! 222 + let shineRect = NSRect( 223 + along: axis, 224 + at: knobRect.origin[axis] + 3, 225 + across: knobRect.origin[axis.opposite] - 6, 226 + length: knobRect.size[axis] - 6, 227 + breadth: 10 228 + ) 229 + let shinePath = NSBezierPath(roundedRect: shineRect, xRadius: 5, yRadius: 5) 230 230 231 - let shineRect = NSRect( 232 - along: axis, 233 - at: knobRect.origin[axis] + 3, 234 - across: knobRect.origin[axis.opposite] - 6, 235 - length: knobRect.size[axis] - 6, 236 - breadth: 10 237 - ) 238 - let shinePath = NSBezierPath(roundedRect: shineRect, xRadius: 5, yRadius: 5) 231 + shineGradient.draw(in: shinePath, angle: axis.crossGradientAngle) 232 + } 239 233 240 - shineGradient.draw(in: shinePath, angle: axis.crossGradientAngle) 241 - NSGraphicsContext.restoreGraphicsState() 242 - } 234 + // trailing cross edge glow 235 + NSGraphicsContext.scope { 236 + let glowGradient = NSGradient(colors: [ 237 + .clear, 238 + .clear, 239 + baseColor.highlight(withLevel: 0.6)! 240 + ])! 243 241 244 - // trailing cross edge glow 245 - do { 246 - NSGraphicsContext.saveGraphicsState() 247 - 248 - let glowGradient = NSGradient(colors: [ 249 - .clear, 250 - .clear, 251 - baseColor.highlight(withLevel: 0.6)! 252 - ])! 242 + let glowPath = NSBezierPath( 243 + roundedRect: knobRect.insetBy(along: axis, length: 1, breadth: 0), 244 + xRadius: radius, 245 + yRadius: radius 246 + ) 247 + glowGradient.draw(in: glowPath, angle: axis.crossGradientAngle) 248 + } 253 249 254 - let glowPath = NSBezierPath( 255 - roundedRect: knobRect.insetBy(along: axis, length: 1, breadth: 0), 256 - xRadius: radius, 257 - yRadius: radius 258 - ) 259 - glowGradient.draw(in: glowPath, angle: axis.crossGradientAngle) 260 - 261 - NSGraphicsContext.restoreGraphicsState() 262 - } 263 - 264 - // leading cross edge glow 265 - do { 266 - NSGraphicsContext.saveGraphicsState() 267 - 268 - let glowGradient = NSGradient(colors: [ 269 - baseColor.highlight(withLevel: 0.6)!, 270 - .clear, 271 - .clear 272 - ])! 250 + // leading cross edge glow 251 + NSGraphicsContext.scope { 252 + let glowGradient = NSGradient(colors: [ 253 + baseColor.highlight(withLevel: 0.6)!, 254 + .clear, 255 + .clear 256 + ])! 273 257 274 - let glowPath = NSBezierPath( 275 - roundedRect: knobRect.insetBy(along: axis, length: 1, breadth: 0), 276 - xRadius: radius, 277 - yRadius: radius 278 - ) 279 - glowGradient.draw(in: glowPath, angle: axis.crossGradientAngle) 280 - NSGraphicsContext.restoreGraphicsState() 258 + let glowPath = NSBezierPath( 259 + roundedRect: knobRect.insetBy(along: axis, length: 1, breadth: 0), 260 + xRadius: radius, 261 + yRadius: radius 262 + ) 263 + glowGradient.draw(in: glowPath, angle: axis.crossGradientAngle) 264 + } 281 265 } 282 266 283 - NSGraphicsContext.restoreGraphicsState() 284 267 } 285 - 286 - NSGraphicsContext.restoreGraphicsState() 287 268 } 288 269 289 270 public override func drawKnobSlot(in slotRect: NSRect, highlight flag: Bool) { ··· 293 274 NSColor.windowBackgroundColor.highlight(withLevel: 0.05)!.setFill() 294 275 bedPath.fill() 295 276 296 - NSGraphicsContext.saveGraphicsState() 297 - 298 - bedPath.addClip() 299 - 300 - let shadow = NSShadow() 301 - shadow.shadowColor = .black.withAlphaComponent(0.6) 302 - shadow.shadowOffset = NSSize(width: 0, height: 0) 303 - shadow.shadowBlurRadius = 3 304 - shadow.set() 305 - 306 - let outerRect = slotRect.insetBy(dx: -10, dy: -10) 307 - let outerPath = NSBezierPath(rect: outerRect) 308 - outerPath.append(bedPath) 309 - outerPath.windingRule = .evenOdd 310 - NSColor.windowBackgroundColor.setFill() 311 - outerPath.fill() 312 - 313 - NSGraphicsContext.restoreGraphicsState() 277 + NSGraphicsContext.scope { 278 + bedPath.addClip() 279 + 280 + let shadow = NSShadow() 281 + shadow.shadowColor = .black.withAlphaComponent(0.6) 282 + shadow.shadowOffset = NSSize(width: 0, height: 0) 283 + shadow.shadowBlurRadius = 3 284 + shadow.set() 285 + 286 + let outerRect = slotRect.insetBy(dx: -10, dy: -10) 287 + let outerPath = NSBezierPath(rect: outerRect) 288 + outerPath.append(bedPath) 289 + outerPath.windingRule = .evenOdd 290 + NSColor.windowBackgroundColor.setFill() 291 + outerPath.fill() 292 + } 314 293 } 315 294 } 316 295 ··· 339 318 340 319 return [ 341 320 (NSPoint(along: self, at: mainMin, across: crossMin), NSPoint(along: self, at: mainMax, across: crossMin)), 342 - (NSPoint(along: self, at: mainMin, across: crossMax), NSPoint(along: self, at: mainMax, across: crossMax)), 321 + (NSPoint(along: self, at: mainMin, across: crossMax), NSPoint(along: self, at: mainMax, across: crossMax)) 343 322 ] 344 323 } 345 324 }
+31 -32
Sources/AquaKit/Source Lists/SourceListBottomBarViewController.swift
··· 29 29 } 30 30 31 31 override func draw(_ dirtyRect: NSRect) { 32 - NSGraphicsContext.saveGraphicsState() 33 - 34 - var alpha = 1.0 35 - if let window, !window.isKeyWindow { 36 - alpha *= 0.6 32 + NSGraphicsContext.scope { 33 + var alpha = 1.0 34 + if let window, !window.isKeyWindow { 35 + alpha *= 0.6 36 + } 37 + if effectiveAppearance.isDarkAqua { 38 + alpha *= 0.3 39 + } 40 + 41 + NSGraphicsContext.current?.cgContext.setAlpha(alpha) 42 + 43 + let color1 = NSColor( 44 + light: NSColor(white: 0.98, alpha: 1), 45 + dark: NSColor(white: 0.98, alpha: 1), 46 + ) 47 + let color2 = NSColor( 48 + light: NSColor(white: 0.96, alpha: 1), 49 + dark: NSColor.graphiteColor.highlight(withLevel: 0.7)! 50 + ) 51 + let color3 = NSColor( 52 + light: NSColor(white: 0.92, alpha: 1), 53 + dark: NSColor.graphiteColor.shadow(withLevel: 0.2)! 54 + ) 55 + 56 + let gradient = NSGradient( 57 + colorsAndLocations: (color1, 0), 58 + (color2, 0.48), 59 + (color3, 0.52), 60 + ) 61 + 62 + gradient?.draw(in: bounds, angle: 270) 37 63 } 38 - if effectiveAppearance.isDarkAqua { 39 - alpha *= 0.3 40 - } 41 - 42 - NSGraphicsContext.current?.cgContext.setAlpha(alpha) 43 - 44 - let color1 = NSColor( 45 - light: NSColor(white: 0.98, alpha: 1), 46 - dark: NSColor(white: 0.98, alpha: 1), 47 - ) 48 - let color2 = NSColor( 49 - light: NSColor(white: 0.96, alpha: 1), 50 - dark: NSColor.graphiteColor.highlight(withLevel: 0.7)! 51 - ) 52 - let color3 = NSColor( 53 - light: NSColor(white: 0.92, alpha: 1), 54 - dark: NSColor.graphiteColor.shadow(withLevel: 0.2)! 55 - ) 56 - 57 - let gradient = NSGradient( 58 - colorsAndLocations: (color1, 0), 59 - (color2, 0.48), 60 - (color3, 0.52), 61 - ) 62 - 63 - gradient?.draw(in: bounds, angle: 270) 64 - NSGraphicsContext.restoreGraphicsState() 65 64 66 65 NSColor.aquaSeparatorColor.setFill() 67 66 NSBezierPath.fill(NSRect(x: bounds.minX, y: bounds.maxY - 1, width: bounds.width, height: 1))
+6 -7
Sources/AquaKit/Table Headers/AquaTableCornerView.swift
··· 17 17 } 18 18 19 19 override open func draw(_ dirtyRect: NSRect) { 20 - NSGraphicsContext.saveGraphicsState() 21 - if let window, !window.isKeyWindow { 22 - NSGraphicsContext.current?.cgContext.setAlpha(0.4) 20 + NSGraphicsContext.scope { 21 + if let window, !window.isKeyWindow { 22 + NSGraphicsContext.current?.cgContext.setAlpha(0.4) 23 + } 24 + 25 + AquaTableHeaderCell.backgroundFillGradient.draw(in: bounds, angle: -90) 23 26 } 24 - 25 - AquaTableHeaderCell.backgroundFillGradient.draw(in: bounds, angle: -90) 26 - 27 - NSGraphicsContext.restoreGraphicsState() 28 27 29 28 NSColor.aquaSeparatorColor.setFill() 30 29 NSBezierPath.fill(NSRect(x: bounds.minX, y: bounds.maxY - 1, width: bounds.width, height: 1))
+5 -5
Sources/AquaKit/Table Headers/AquaTableHeaderView.swift
··· 18 18 } 19 19 20 20 override open func draw(_ dirtyRect: NSRect) { 21 - NSGraphicsContext.saveGraphicsState() 22 - if let window, !window.isKeyWindow { 23 - NSGraphicsContext.current?.cgContext.setAlpha(0.4) 21 + NSGraphicsContext.scope { 22 + if let window, !window.isKeyWindow { 23 + NSGraphicsContext.current?.cgContext.setAlpha(0.4) 24 + } 25 + super.draw(dirtyRect) 24 26 } 25 - super.draw(dirtyRect) 26 - NSGraphicsContext.restoreGraphicsState() 27 27 28 28 NSColor.aquaSeparatorColor.setFill() 29 29 NSBezierPath.fill(NSRect(x: bounds.minX, y: bounds.maxY - 1, width: bounds.width, height: 1))
+51 -52
Sources/AquaKit/Windows/AquaTrafficLightButton.swift
··· 71 71 } 72 72 73 73 override open func draw(_ dirtyRect: NSRect) { 74 - NSGraphicsContext.saveGraphicsState() 74 + NSGraphicsContext.scope { 75 75 76 - var color = baseColor 77 - if NSColor.controlAccentColor.isGrayscale { 78 - color = .graphiteColor 79 - } 80 - if isHighlighted { 81 - color = color.shadow(withLevel: 0.4)! 82 - } 83 - if let window, !window.isKeyWindow { 84 - color = .graphiteColor.highlight(withLevel: 0.8)! 85 - NSGraphicsContext.current?.cgContext.setAlpha(0.4) 86 - } 87 - if effectiveAppearance.isDarkAqua { 88 - color = color.blended(withFraction: 0.5, of: .graphiteColor.shadow(withLevel: 0.9)!)! 89 - } 76 + var color = baseColor 77 + if NSColor.controlAccentColor.isGrayscale { 78 + color = .graphiteColor 79 + } 80 + if isHighlighted { 81 + color = color.shadow(withLevel: 0.4)! 82 + } 83 + if let window, !window.isKeyWindow { 84 + color = .graphiteColor.highlight(withLevel: 0.8)! 85 + NSGraphicsContext.current?.cgContext.setAlpha(0.4) 86 + } 87 + if effectiveAppearance.isDarkAqua { 88 + color = color.blended(withFraction: 0.5, of: .graphiteColor.shadow(withLevel: 0.9)!)! 89 + } 90 90 91 - let strokeWidth = 1.0 92 - let bounds = bounds 93 - let ellipse = NSBezierPath(ovalIn: bounds) 91 + let strokeWidth = 1.0 92 + let bounds = bounds 93 + let ellipse = NSBezierPath(ovalIn: bounds) 94 94 95 - NSGraphicsContext.saveGraphicsState() 96 - ellipse.setClip() 97 - do { 98 - ellipse.lineWidth = strokeWidth 99 - color.shadow(withLevel: 0.4)!.setFill() 100 - ellipse.fill() 101 - } 95 + NSGraphicsContext.scope { 96 + ellipse.setClip() 97 + do { 98 + ellipse.lineWidth = strokeWidth 99 + color.shadow(withLevel: 0.4)!.setFill() 100 + ellipse.fill() 101 + } 102 + 103 + do { 104 + let bottomGlowGradient = NSGradient( 105 + colorsAndLocations: (.white, 0.0), 106 + (.white.withAlphaComponent(0.8), 0.2), 107 + (.clear, 0.5) 108 + )! 102 109 103 - do { 104 - let bottomGlowGradient = NSGradient( 105 - colorsAndLocations: (.white, 0.0), 106 - (.white.withAlphaComponent(0.8), 0.2), 107 - (.clear, 0.5) 108 - )! 110 + let gradientRect = bounds.insetBy(dx: 0, dy: 0) 111 + bottomGlowGradient.draw(in: gradientRect, relativeCenterPosition: NSPoint(x: 0, y: -0.7)) 112 + } 109 113 110 - let gradientRect = bounds.insetBy(dx: 0, dy: 0) 111 - bottomGlowGradient.draw(in: gradientRect, relativeCenterPosition: NSPoint(x: 0, y: -0.7)) 112 - } 114 + do { 115 + let centerGlowGradient = NSGradient( 116 + colorsAndLocations: (color.withAlphaComponent(0.7), 0.0), 117 + (color.withAlphaComponent(0.5), 0.5), 118 + (color.withAlphaComponent(0.1), 1), 119 + )! 113 120 114 - do { 115 - let centerGlowGradient = NSGradient( 116 - colorsAndLocations: (color.withAlphaComponent(0.7), 0.0), 117 - (color.withAlphaComponent(0.5), 0.5), 118 - (color.withAlphaComponent(0.1), 1), 119 - )! 121 + centerGlowGradient.draw(in: bounds, relativeCenterPosition: .zero) 122 + } 120 123 121 - centerGlowGradient.draw(in: bounds, relativeCenterPosition: .zero) 122 - } 124 + do { 125 + let innerEllipse = NSBezierPath(ovalIn: bounds.insetBy(dx: bounds.width * 0.05, dy: bounds.width * 0.05)) 126 + let innerEllipseGradient = NSGradient(colorsAndLocations: (.white.withAlphaComponent(0.7), 0.0), (.clear, 0.4))! 127 + innerEllipseGradient.draw(in: innerEllipse, angle: 270) 128 + } 129 + } 123 130 124 - do { 125 - let innerEllipse = NSBezierPath(ovalIn: bounds.insetBy(dx: bounds.width * 0.05, dy: bounds.width * 0.05)) 126 - let innerEllipseGradient = NSGradient(colorsAndLocations: (.white.withAlphaComponent(0.7), 0.0), (.clear, 0.4))! 127 - innerEllipseGradient.draw(in: innerEllipse, angle: 270) 131 + color.shadow(withLevel: 0.7)!.setStroke() 132 + ellipse.stroke() 128 133 } 129 - NSGraphicsContext.restoreGraphicsState() 130 - 131 - color.shadow(withLevel: 0.7)!.setStroke() 132 - ellipse.stroke() 133 - 134 - NSGraphicsContext.restoreGraphicsState() 135 134 } 136 135 137 136 @objc public func setDocumentEdited(_ edited: Bool) {}
+34 -35
Sources/AquaKit/Windows/AquaWindowToolbarButton.swift
··· 18 18 } 19 19 20 20 override open func draw(_ dirtyRect: NSRect) { 21 - NSGraphicsContext.saveGraphicsState() 21 + NSGraphicsContext.scope { 22 22 23 - if let window, !window.isKeyWindow { 24 - NSGraphicsContext.current?.cgContext.setAlpha( 25 - effectiveAppearance.isDarkAqua ? 0.3 : 0.4 26 - ) 27 - } 23 + if let window, !window.isKeyWindow { 24 + NSGraphicsContext.current?.cgContext.setAlpha( 25 + effectiveAppearance.isDarkAqua ? 0.3 : 0.4 26 + ) 27 + } 28 28 29 - let lozengeRect = bounds.insetBy(dx: 0, dy: 2) 30 - let lozenge = NSBezierPath(roundedRect: lozengeRect, xRadius: 6, yRadius: 6) 31 - lozenge.lineWidth = 1.0 32 - NSColor.gray.shadow(withLevel: 0.5)!.setStroke() 33 - lozenge.stroke() 29 + let lozengeRect = bounds.insetBy(dx: 0, dy: 2) 30 + let lozenge = NSBezierPath(roundedRect: lozengeRect, xRadius: 6, yRadius: 6) 31 + lozenge.lineWidth = 1.0 32 + NSColor.gray.shadow(withLevel: 0.5)!.setStroke() 33 + lozenge.stroke() 34 34 35 - func shadow(_ color: NSColor) -> NSColor { 36 - color.shadow(withLevel: 0.2)! 37 - } 35 + func shadow(_ color: NSColor) -> NSColor { 36 + color.shadow(withLevel: 0.2)! 37 + } 38 38 39 - let gradient = NSGradient( 40 - colorsAndLocations: ( 41 - #colorLiteral(red: 0.7792062163, green: 0.7657493949, blue: 0.7566991448, alpha: 1).modifyDark(shadow(_:)), 0.0 42 - ), 43 - (#colorLiteral(red: 0.9971552491, green: 0.9922525287, blue: 0.9795755744, alpha: 1).modifyDark(shadow(_:)), 1.0) 44 - )! 45 - gradient.draw(in: lozenge, angle: 270) 39 + let gradient = NSGradient( 40 + colorsAndLocations: ( 41 + #colorLiteral(red: 0.7792062163, green: 0.7657493949, blue: 0.7566991448, alpha: 1).modifyDark(shadow(_:)), 0.0 42 + ), 43 + (#colorLiteral(red: 0.9971552491, green: 0.9922525287, blue: 0.9795755744, alpha: 1).modifyDark(shadow(_:)), 1.0) 44 + )! 45 + gradient.draw(in: lozenge, angle: 270) 46 46 47 - do { 48 - let shinePath = NSBezierPath( 49 - roundedRect: lozengeRect.insetBy(dx: bounds.width * 0.02, dy: bounds.width * 0.02), 50 - xRadius: 6, 51 - yRadius: 6 52 - ) 53 - let shineGradient = NSGradient(colorsAndLocations: (.white, 0.0), (.clear, 0.4))! 54 - shineGradient.draw(in: shinePath, angle: 270) 55 - } 47 + do { 48 + let shinePath = NSBezierPath( 49 + roundedRect: lozengeRect.insetBy(dx: bounds.width * 0.02, dy: bounds.width * 0.02), 50 + xRadius: 6, 51 + yRadius: 6 52 + ) 53 + let shineGradient = NSGradient(colorsAndLocations: (.white, 0.0), (.clear, 0.4))! 54 + shineGradient.draw(in: shinePath, angle: 270) 55 + } 56 56 57 - if isHighlighted { 58 - NSColor.gray.withAlphaComponent(0.4).setFill() 59 - lozenge.fill() 57 + if isHighlighted { 58 + NSColor.gray.withAlphaComponent(0.4).setFill() 59 + lozenge.fill() 60 + } 60 61 } 61 - 62 - NSGraphicsContext.restoreGraphicsState() 63 62 } 64 63 }