From ff7a66253654198b1560ace2d010052b086763ce Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 14 Sep 2018 12:18:42 +0700 Subject: [PATCH] Support Mojave dark mode --- .swiftlint.yml | 4 +- Gifski/MainWindowController.swift | 13 +++--- Gifski/Vendor/CircularProgress.swift | 22 ++++++---- Gifski/Vendor/Defaults.swift | 2 +- Gifski/Vendor/DockProgress.swift | 62 ++++++++++++++-------------- Gifski/VideoDropView.swift | 2 +- Gifski/util.swift | 24 +++++++++-- 7 files changed, 77 insertions(+), 52 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index a07b5f02..f6f89ac1 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -2,12 +2,14 @@ disabled_rules: - file_length - line_length - identifier_name + - todo # Enabled this again! - vertical_whitespace - force_cast - force_try - large_tuple - function_body_length - nesting # Disabled because of https://github.com/realm/SwiftLint/issues/1151 + - type_body_length opt_in_rules: - empty_count - prohibited_super_call @@ -20,7 +22,6 @@ opt_in_rules: - explicit_init - switch_case_on_newline - number_separator - - extension_access_modifier - closure_end_indentation - closure_spacing - operator_usage_whitespace @@ -53,6 +54,7 @@ opt_in_rules: - multiline_arguments - anyobject_protocol - redundant_type_annotation + - no_extension_access_modifier force_cast: warning force_unwrapping: warning number_separator: diff --git a/Gifski/MainWindowController.swift b/Gifski/MainWindowController.swift index 4a1a76a0..7054154b 100644 --- a/Gifski/MainWindowController.swift +++ b/Gifski/MainWindowController.swift @@ -36,16 +36,19 @@ final class MainWindowController: NSWindowController { with(window) { $0.delegate = self - $0.appearance = NSAppearance(named: .vibrantLight) $0.titleVisibility = .hidden - $0.styleMask = [.titled, .closable, .miniaturizable, .fullSizeContentView] + $0.styleMask = [ + .titled, + .closable, + .miniaturizable, + .fullSizeContentView + ] $0.tabbingMode = .disallowed + $0.collectionBehavior = .fullScreenNone $0.titlebarAppearsTransparent = true $0.isMovableByWindowBackground = true $0.isRestorable = false - - let vibrancyView = $0.contentView?.insertVibrancyView() - vibrancyView?.state = .active + $0.makeVibrant() } view?.addSubview(circularProgress) diff --git a/Gifski/Vendor/CircularProgress.swift b/Gifski/Vendor/CircularProgress.swift index 365a901c..8f11f78b 100644 --- a/Gifski/Vendor/CircularProgress.swift +++ b/Gifski/Vendor/CircularProgress.swift @@ -30,9 +30,7 @@ public final class CircularProgress: NSView { @IBInspectable public var color: NSColor = .systemBlue { didSet { - backgroundCircle.strokeColor = color.with(alpha: 0.5).cgColor - progressCircle.strokeColor = color.cgColor - progressLabel.foregroundColor = color.cgColor + needsDisplay = true } } @@ -70,6 +68,12 @@ public final class CircularProgress: NSView { commonInit() } + override public func updateLayer() { + backgroundCircle.strokeColor = color.with(alpha: 0.5).cgColor + progressCircle.strokeColor = color.cgColor + progressLabel.foregroundColor = color.cgColor + } + private func commonInit() { wantsLayer = true layer?.addSublayer(backgroundCircle) @@ -93,7 +97,7 @@ public final class CircularProgress: NSView { /// util.swift /// -private extension CALayer { +extension CALayer { static func animate( duration: TimeInterval = 1, delay: TimeInterval = 0, @@ -160,7 +164,7 @@ extension CALayer { } -private extension NSFont { +extension NSFont { static let helveticaNeueLight = NSFont(name: "HelveticaNeue-Light", size: 0) } @@ -172,7 +176,7 @@ private extension NSFont { //} -private extension NSBezierPath { +extension NSBezierPath { static func circle(radius: Double, center: CGPoint) -> NSBezierPath { let path = NSBezierPath() path.appendArc( @@ -200,7 +204,7 @@ private extension NSBezierPath { } -private extension CAShapeLayer { +extension CAShapeLayer { static func circle(radius: Double, center: CGPoint) -> CAShapeLayer { return CAShapeLayer(path: NSBezierPath.circle(radius: radius, center: center)) } @@ -212,7 +216,7 @@ private extension CAShapeLayer { } -private extension CATextLayer { +extension CATextLayer { /// Initializer with better defaults convenience init(text: String, fontSize: Double? = nil, color: NSColor? = nil) { self.init() @@ -239,7 +243,7 @@ private extension CATextLayer { } -private final class ProgressCircleShapeLayer: CAShapeLayer { +final class ProgressCircleShapeLayer: CAShapeLayer { convenience init(radius: Double, center: CGPoint) { self.init() fillColor = nil diff --git a/Gifski/Vendor/Defaults.swift b/Gifski/Vendor/Defaults.swift index 7dd580fa..cc66013c 100644 --- a/Gifski/Vendor/Defaults.swift +++ b/Gifski/Vendor/Defaults.swift @@ -52,7 +52,7 @@ public final class Defaults { // Has to be `defaults` lowercase until Swift supports static subscripts… public let defaults = Defaults() -public extension UserDefaults { +extension UserDefaults { private func _get(_ key: String) -> T? { if isNativelySupportedType(T.self) { return object(forKey: key) as? T diff --git a/Gifski/Vendor/DockProgress.swift b/Gifski/Vendor/DockProgress.swift index abfaa8d0..8867a28d 100644 --- a/Gifski/Vendor/DockProgress.swift +++ b/Gifski/Vendor/DockProgress.swift @@ -127,39 +127,39 @@ let label = with(NSTextField()) { //} -private extension NSBezierPath { - static func progressCircle(radius: Double, center: CGPoint) -> NSBezierPath { - let startAngle: CGFloat = 90 - let path = NSBezierPath() - path.appendArc( - withCenter: center, - radius: CGFloat(radius), - startAngle: startAngle, - endAngle: startAngle - 360, - clockwise: true - ) - return path - } -} - +//extension NSBezierPath { +// static func progressCircle(radius: Double, center: CGPoint) -> NSBezierPath { +// let startAngle: CGFloat = 90 +// let path = NSBezierPath() +// path.appendArc( +// withCenter: center, +// radius: CGFloat(radius), +// startAngle: startAngle, +// endAngle: startAngle - 360, +// clockwise: true +// ) +// return path +// } +//} -private final class ProgressCircleShapeLayer: CAShapeLayer { - convenience init(radius: Double, center: CGPoint) { - self.init() - fillColor = nil - lineCap = .round - path = NSBezierPath.progressCircle(radius: radius, center: center).cgPath - } - var progress: Double { - get { - return Double(strokeEnd) - } - set { - strokeEnd = CGFloat(newValue) - } - } -} +//final class ProgressCircleShapeLayer: CAShapeLayer { +// convenience init(radius: Double, center: CGPoint) { +// self.init() +// fillColor = nil +// lineCap = .round +// path = NSBezierPath.progressCircle(radius: radius, center: center).cgPath +// } +// +// var progress: Double { +// get { +// return Double(strokeEnd) +// } +// set { +// strokeEnd = CGFloat(newValue) +// } +// } +//} //private extension NSColor { diff --git a/Gifski/VideoDropView.swift b/Gifski/VideoDropView.swift index 18e43c8d..d58a346a 100644 --- a/Gifski/VideoDropView.swift +++ b/Gifski/VideoDropView.swift @@ -10,7 +10,7 @@ class DropView: SSView { } private let dropLabel = with(Label()) { - $0.textColor = NSColor.textColor.with(alpha: 0.5) + $0.textColor = NSColor.secondaryLabelColor } var highlightColor: NSColor { diff --git a/Gifski/util.swift b/Gifski/util.swift index 4e7bfa5c..56ba9bc6 100644 --- a/Gifski/util.swift +++ b/Gifski/util.swift @@ -161,6 +161,7 @@ extension NSWindow { } } + extension NSWindowController { /// Expose the `view` like in NSViewController var view: NSView? { @@ -172,20 +173,35 @@ extension NSWindowController { extension NSView { @discardableResult func insertVibrancyView( - withAppearance appearance: NSAppearance.Name = .vibrantLight, - material: NSVisualEffectView.Material = .appearanceBased + material: NSVisualEffectView.Material = .appearanceBased, + blendingMode: NSVisualEffectView.BlendingMode = .behindWindow, + appearanceName: NSAppearance.Name? = nil ) -> NSVisualEffectView { let view = NSVisualEffectView(frame: bounds) view.autoresizingMask = [.width, .height] - view.blendingMode = .behindWindow - view.appearance = NSAppearance(named: appearance) view.material = material + view.blendingMode = blendingMode + + if let appearanceName = appearanceName { + view.appearance = NSAppearance(named: appearanceName) + } + addSubview(view, positioned: .below, relativeTo: nil) + return view } } +extension NSWindow { + func makeVibrant() { + if #available(OSX 10.14, *) { + contentView?.insertVibrancyView(material: .underWindowBackground) + } + } +} + + extension NSWindow { var toolbarView: NSView? { return standardWindowButton(.closeButton)?.superview