From 5edb0c0ee7bff3a9bf9447037d21c26007ce074d Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 22 Mar 2020 18:45:24 -0400 Subject: [PATCH] Adds animated fade-out to volume control. Bumps macOS version to 10.12.2. --- .../Clock Signal.xcodeproj/project.pbxproj | 8 +++- .../Documents/MachineDocument.swift | 37 ++++++++++++++++++- .../Mac/Clock Signal/Views/CSOpenGLView.m | 1 + 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 881f5f442..400a6be4f 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -204,6 +204,7 @@ 4B4B1A3D200198CA00A0F866 /* KonamiSCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */; }; 4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; }; 4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; }; + 4B50AF80242817F40099BBD7 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B50AF7F242817F40099BBD7 /* QuartzCore.framework */; }; 4B54C0BC1F8D8E790050900F /* KeyboardMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0BB1F8D8E790050900F /* KeyboardMachine.cpp */; }; 4B54C0BF1F8D8F450050900F /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0BD1F8D8F450050900F /* Keyboard.cpp */; }; 4B54C0C21F8D91CD0050900F /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0C11F8D91CD0050900F /* Keyboard.cpp */; }; @@ -1104,6 +1105,7 @@ 4B4DC8271D2C2470003C5BF8 /* C1540.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = C1540.hpp; sourceTree = ""; }; 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerialBus.cpp; sourceTree = ""; }; 4B4DC82A1D2C27A4003C5BF8 /* SerialBus.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SerialBus.hpp; sourceTree = ""; }; + 4B50AF7F242817F40099BBD7 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 4B51F70920A521D700AFA2C1 /* Source.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Source.hpp; sourceTree = ""; }; 4B51F70A20A521D700AFA2C1 /* Observer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Observer.hpp; sourceTree = ""; }; 4B54C0BB1F8D8E790050900F /* KeyboardMachine.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = KeyboardMachine.cpp; sourceTree = ""; }; @@ -1793,6 +1795,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4B50AF80242817F40099BBD7 /* QuartzCore.framework in Frameworks */, 4BC76E6B1C98F43700E6EF73 /* Accelerate.framework in Frameworks */, 4B69FB461C4D950F00B5F0AA /* libz.tbd in Frameworks */, ); @@ -1820,6 +1823,7 @@ 4B055A761FAE78210060FFFF /* Frameworks */ = { isa = PBXGroup; children = ( + 4B50AF7F242817F40099BBD7 /* QuartzCore.framework */, 4B055AF01FAE9C080060FFFF /* OpenGL.framework */, 4B055A771FAE78210060FFFF /* SDL2.framework */, ); @@ -5137,7 +5141,7 @@ GCC_WARN_UNUSED_LABEL = YES; INFOPLIST_FILE = "Clock Signal/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.12.2; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "-Wreorder", @@ -5185,7 +5189,7 @@ GCC_WARN_UNUSED_LABEL = YES; INFOPLIST_FILE = "Clock Signal/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.12.2; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "-Wreorder", diff --git a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift index c8bf94266..c57acf11f 100644 --- a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift +++ b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift @@ -8,6 +8,7 @@ import AudioToolbox import Cocoa +import QuartzCore class MachineDocument: NSDocument, @@ -723,13 +724,47 @@ class MachineDocument: } } + // This class is pure nonsense to work around Xcode's opaque behaviour. + // If I make the main class a sub of CAAnimationDelegate then the compiler + // generates a bridging header that doesn't include QuartzCore and therefore + // can't find a declaration of the CAAnimationDelegate protocol. Doesn't + // seem to matter what I add explicitly to the link stage, which version of + // macOS I set as the target, etc. + // + // So, the workaround: make my CAAnimationDelegate something that doesn't + // appear in the bridging header. + fileprivate class ViewFader: NSObject, CAAnimationDelegate { + var volumeView: NSView + + init(view: NSView) { + volumeView = view + } + + func animationDidStop(_ anim: CAAnimation, finished flag: Bool) { + volumeView.isHidden = true + } + } + fileprivate var animationFader: ViewFader? = nil + func openGLViewDidShowOSMouseCursor(_ view: CSOpenGLView) { // The OS mouse cursor became visible, so show the volume controls. + volumeView.layer?.removeAllAnimations() + animationFader = nil volumeView.isHidden = false + volumeView.layer?.opacity = 1.0 } func openGLViewWillHideOSMouseCursor(_ view: CSOpenGLView) { // The OS mouse cursor will be hidden, so hide the volume controls. - volumeView.isHidden = true + if !volumeView.isHidden && volumeView.layer?.animation(forKey: "opacity") == nil { + let fadeAnimation = CABasicAnimation(keyPath: "opacity") + fadeAnimation.fromValue = 1.0 + fadeAnimation.toValue = 0.0 + fadeAnimation.duration = 0.5 + animationFader = ViewFader(view: volumeView) + fadeAnimation.delegate = animationFader + volumeView.layer?.add(fadeAnimation, forKey: "opacity") + volumeView.layer?.opacity = 0.0 + } } } diff --git a/OSBindings/Mac/Clock Signal/Views/CSOpenGLView.m b/OSBindings/Mac/Clock Signal/Views/CSOpenGLView.m index b6a1246c9..0184b38ed 100644 --- a/OSBindings/Mac/Clock Signal/Views/CSOpenGLView.m +++ b/OSBindings/Mac/Clock Signal/Views/CSOpenGLView.m @@ -307,6 +307,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt [super mouseExited:event]; [_mouseHideTimer invalidate]; _mouseHideTimer = nil; + [self.delegate openGLViewWillHideOSMouseCursor:self]; } - (void)releaseMouse {