From 77dc419ada6d8a895da0c42a4b94670339ccffe6 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 23 Aug 2017 17:06:04 +0700 Subject: [PATCH] Big refactor --- Touch Bar Simulator.xcodeproj/project.pbxproj | 4 + Touch Bar Simulator/ToolbarSlider.swift | 56 ++++++-------- Touch Bar Simulator/main.swift | 75 +++++++++---------- Touch Bar Simulator/util.swift | 22 ++++++ 4 files changed, 82 insertions(+), 75 deletions(-) create mode 100644 Touch Bar Simulator/util.swift diff --git a/Touch Bar Simulator.xcodeproj/project.pbxproj b/Touch Bar Simulator.xcodeproj/project.pbxproj index 351692e..4dd37de 100644 --- a/Touch Bar Simulator.xcodeproj/project.pbxproj +++ b/Touch Bar Simulator.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ E34F2FFC1E89A77400217535 /* DVTDeviceFoundation.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E34F2FFA1E89A77400217535 /* DVTDeviceFoundation.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; E34F31CD1E89AD7300217535 /* DFRSupportKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E34F31CC1E89AD7300217535 /* DFRSupportKit.framework */; }; E34F31CE1E89AD7300217535 /* DFRSupportKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E34F31CC1E89AD7300217535 /* DFRSupportKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + E35831A41F4D7EE0003BE371 /* util.swift in Sources */ = {isa = PBXBuildFile; fileRef = E35831A31F4D7EE0003BE371 /* util.swift */; }; E3FA3A8B1E784C4900A7F2EA /* DVTFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E3FA3A8A1E784C4900A7F2EA /* DVTFoundation.framework */; }; E3FA3A8D1E784C5F00A7F2EA /* DVTFoundation.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E3FA3A8A1E784C4900A7F2EA /* DVTFoundation.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; E3FA3A921E784C7D00A7F2EA /* DVTKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E3FA3A911E784C7D00A7F2EA /* DVTKit.framework */; }; @@ -66,6 +67,7 @@ E30988DE1E88DD060078CA9E /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = Carthage/Build/Mac/Sparkle.framework; sourceTree = ""; }; E34F2FFA1E89A77400217535 /* DVTDeviceFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DVTDeviceFoundation.framework; path = /Applications/Xcode.app/Contents/SharedFrameworks/DVTDeviceFoundation.framework; sourceTree = ""; }; E34F31CC1E89AD7300217535 /* DFRSupportKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = DFRSupportKit.framework; sourceTree = ""; }; + E35831A31F4D7EE0003BE371 /* util.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = util.swift; sourceTree = ""; }; E3FA3A8A1E784C4900A7F2EA /* DVTFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DVTFoundation.framework; path = /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework; sourceTree = ""; }; E3FA3A911E784C7D00A7F2EA /* DVTKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DVTKit.framework; path = /Applications/Xcode.app/Contents/SharedFrameworks/DVTKit.framework; sourceTree = ""; }; E3FA3A951E784DB100A7F2EA /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/MacOSX.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; @@ -126,6 +128,7 @@ isa = PBXGroup; children = ( E3FE2CC21E726CE800C6713A /* main.swift */, + E35831A31F4D7EE0003BE371 /* util.swift */, AF6C7BC51E7FAF38004A27E0 /* ToolbarSlider.swift */, E3FE2CD21E726EA100C6713A /* Touch Bar Simulator-Bridging-Header.h */, E3FE2CC41E726CE800C6713A /* Assets.xcassets */, @@ -226,6 +229,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + E35831A41F4D7EE0003BE371 /* util.swift in Sources */, AF6C7BC61E7FAF38004A27E0 /* ToolbarSlider.swift in Sources */, E3FE2CC31E726CE800C6713A /* main.swift in Sources */, ); diff --git a/Touch Bar Simulator/ToolbarSlider.swift b/Touch Bar Simulator/ToolbarSlider.swift index 437cbf7..5560967 100644 --- a/Touch Bar Simulator/ToolbarSlider.swift +++ b/Touch Bar Simulator/ToolbarSlider.swift @@ -1,36 +1,28 @@ -// -// ToolbarSlider.swift -// Touch Bar Simulator -// -// Created by Wayne Yeh on 2017/3/20 -// MIT License © Sindre Sorhus -// - import Cocoa +private let knob: NSImage = { + let frame = CGRect(x: 0, y: 0, width: 32, height: 32) + + let image = NSImage(size: frame.size) + image.lockFocus() + + // Circle + let path = NSBezierPath(roundedRect: frame, xRadius: 4, yRadius: 12) + NSColor.lightGray.set() + path.fill() + + // Border + NSColor.black.set() + path.lineWidth = 2 + path.stroke() + + image.unlockFocus() + return image +}() + private final class ToolbarSliderCell: NSSliderCell { - private static let knob: NSImage = { - let frame = CGRect(x: 0, y: 0, width: 32, height: 32) - - let image = NSImage(size: frame.size) - image.lockFocus() - - // Circle - let path = NSBezierPath(roundedRect: frame, xRadius: 4, yRadius: 12) - NSColor.lightGray.set() - path.fill() - - // Border - NSColor.black.set() - path.lineWidth = 2 - path.stroke() - - image.unlockFocus() - return image - }() - override func drawKnob(_ knobRect: CGRect) { - ToolbarSliderCell.knob.draw(in: knobRect.insetBy(dx: 0, dy: 6.5)) + knob.draw(in: knobRect.insetBy(dx: 0, dy: 6.5)) } } @@ -39,11 +31,7 @@ final class ToolbarSlider: NSSlider { super.init(frame: frame) cell = ToolbarSliderCell() } - - convenience init() { - self.init(frame: .zero) - } - + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } diff --git a/Touch Bar Simulator/main.swift b/Touch Bar Simulator/main.swift index 86315f1..e169451 100644 --- a/Touch Bar Simulator/main.swift +++ b/Touch Bar Simulator/main.swift @@ -1,34 +1,37 @@ -// -// AppDelegate.swift -// Touch Bar Simulator -// -// Created by Sindre Sorhus on 10/03/2017 -// MIT License © Sindre Sorhus -// - import Cocoa import Sparkle +private let defaults = UserDefaults.standard + final class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate { let controller = IDETouchBarSimulatorHostWindowController.simulatorHostWindowController()! - var toolbarView: NSView! + lazy var window: NSWindow = self.controller.window! + lazy var toolbarView: NSView = self.window.toolbarView! + + func applicationWillFinishLaunching(_ notification: Notification) { + defaults.register(defaults: [ + "NSApplicationCrashOnExceptions": true, + "windowTransparency": 0.75 + ]) + } func applicationDidFinishLaunching(_ notification: Notification) { NSApp.servicesProvider = self + window.delegate = self _ = SUUpdater() - controller.window?.delegate = self - toolbarView = controller.window!.standardWindowButton(.closeButton)!.superview! - addScreenshotButton() - addTransparencySlider() + toolbarView.addSubviews( + makeScreenshotButton(), + makeTransparencySlider() + ) } func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true } - func addScreenshotButton() { + func makeScreenshotButton() -> NSButton { let button = NSButton() button.image = #imageLiteral(resourceName: "ScreenshotButton") button.imageScaling = .scaleProportionallyDown @@ -36,43 +39,33 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate { button.bezelStyle = .shadowlessSquare button.frame = CGRect(x: toolbarView.frame.width - 19, y: 4, width: 16, height: 11) button.action = #selector(captureScreenshot) - toolbarView.addSubview(button) + return button + } + + func makeTransparencySlider() -> ToolbarSlider { + let transparency = defaults.double(forKey: "windowTransparency") + let slider = ToolbarSlider() + slider.frame = CGRect(x: toolbarView.frame.width - 150, y: 4, width: 120, height: 11) + slider.action = #selector(setTransparency) + slider.minValue = 0.5 + slider.doubleValue = transparency + window.alphaValue = CGFloat(transparency) + return slider } func captureScreenshot() { let KEY_6: CGKeyCode = 0x58 - let src = CGEventSource(stateID: .hidSystemState) - let keyDown = CGEvent(keyboardEventSource: src, virtualKey: KEY_6, keyDown: true) - let keyUp = CGEvent(keyboardEventSource: src, virtualKey: KEY_6, keyDown: false) - let loc = CGEventTapLocation.cghidEventTap - keyDown?.flags = [.maskShift, .maskCommand] - keyDown?.post(tap: loc) - keyUp?.post(tap: loc) + pressKey(keyCode: KEY_6, flags: [.maskShift, .maskCommand]) } - func addTransparencySlider() { - let slider = ToolbarSlider() - slider.frame = CGRect(x: toolbarView.frame.width - 150, y: 4, width: 120, height: 11) - slider.action = #selector(setTransparency) - toolbarView.addSubview(slider) - - var transparency = UserDefaults.standard.double(forKey: "windowTransparency") - if transparency == 0 { - transparency = 0.75 - } - slider.minValue = 0.5 - slider.doubleValue = transparency - controller.window!.alphaValue = CGFloat(slider.doubleValue) - } - - func setTransparency(sender: NSSlider) { - controller.window!.alphaValue = CGFloat(sender.doubleValue) - UserDefaults.standard.set(sender.doubleValue, forKey: "windowTransparency") + func setTransparency(sender: ToolbarSlider) { + window.alphaValue = CGFloat(sender.doubleValue) + defaults.set(sender.doubleValue, forKey: "windowTransparency") } @objc func toggleView(_ pboard: NSPasteboard, userData: String, error: NSErrorPointer) { - controller.window!.setIsVisible(!controller.window!.isVisible) + window.setIsVisible(!window.isVisible) } } diff --git a/Touch Bar Simulator/util.swift b/Touch Bar Simulator/util.swift new file mode 100644 index 0000000..7f4e668 --- /dev/null +++ b/Touch Bar Simulator/util.swift @@ -0,0 +1,22 @@ +import Cocoa + +extension NSWindow { + var toolbarView: NSView? { + return standardWindowButton(.closeButton)?.superview + } +} + +extension NSView { + func addSubviews(_ subviews: NSView...) { + subviews.forEach { addSubview($0) } + } +} + +func pressKey(keyCode: CGKeyCode, flags: CGEventFlags = []) { + let eventSource = CGEventSource(stateID: .hidSystemState) + let keyDown = CGEvent(keyboardEventSource: eventSource, virtualKey: keyCode, keyDown: true) + let keyUp = CGEvent(keyboardEventSource: eventSource, virtualKey: keyCode, keyDown: false) + keyDown?.flags = flags + keyDown?.post(tap: .cghidEventTap) + keyUp?.post(tap: .cghidEventTap) +}