mirror of
https://github.com/TomHarte/CLK.git
synced 2024-10-01 13:58:20 +00:00
Makes ViewFader
the full master of fading.
This commit is contained in:
parent
616f8efc47
commit
eb8ec1efb1
@ -213,6 +213,16 @@ class MachineDocument:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up a fader for the volume and options.
|
||||||
|
var fadingViews: [NSView] = []
|
||||||
|
if let optionsView = self.optionsView {
|
||||||
|
fadingViews.append(optionsView)
|
||||||
|
}
|
||||||
|
if let volumeView = self.volumeView {
|
||||||
|
fadingViews.append(volumeView)
|
||||||
|
}
|
||||||
|
optionsFader = ViewFader(views: fadingViews)
|
||||||
|
|
||||||
// Create and populate an activity display if required.
|
// Create and populate an activity display if required.
|
||||||
setupActivityDisplay()
|
setupActivityDisplay()
|
||||||
|
|
||||||
@ -608,7 +618,7 @@ class MachineDocument:
|
|||||||
var isBlinking = false
|
var isBlinking = false
|
||||||
}
|
}
|
||||||
private var leds: [String: LED] = [:]
|
private var leds: [String: LED] = [:]
|
||||||
private var activityFader: ViewFader? = nil
|
private var activityFader: ViewFader! = nil
|
||||||
|
|
||||||
func setupActivityDisplay() {
|
func setupActivityDisplay() {
|
||||||
var leds = machine.leds
|
var leds = machine.leds
|
||||||
@ -709,92 +719,85 @@ class MachineDocument:
|
|||||||
// Otherwise, hide it.
|
// Otherwise, hide it.
|
||||||
let litLEDs = self.leds.filter { $0.value.isLit }
|
let litLEDs = self.leds.filter { $0.value.isLit }
|
||||||
if litLEDs.isEmpty {
|
if litLEDs.isEmpty {
|
||||||
self.animateOutView(self.activityView, withDelay: 1.0, fader: activityFader!)
|
activityFader.animateOut(delay: 1.0)
|
||||||
} else {
|
} else {
|
||||||
self.animateInView(self.activityView)
|
activityFader.animateIn()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - In-window panels (i.e. options, volume).
|
// MARK: - In-window panels (i.e. options, volume).
|
||||||
|
|
||||||
private var animationFader: ViewFader? = nil
|
private var optionsFader: ViewFader! = nil
|
||||||
|
|
||||||
var fadingViews: [NSView] {
|
|
||||||
get {
|
|
||||||
var views: [NSView] = []
|
|
||||||
if let optionsView = self.optionsView {
|
|
||||||
views.append(optionsView)
|
|
||||||
}
|
|
||||||
if let volumeView = self.volumeView {
|
|
||||||
views.append(volumeView)
|
|
||||||
}
|
|
||||||
return views
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal func scanTargetViewDidShowOSMouseCursor(_ view: CSScanTargetView) {
|
internal func scanTargetViewDidShowOSMouseCursor(_ view: CSScanTargetView) {
|
||||||
// The OS mouse cursor became visible, so show the volume controls.
|
// The OS mouse cursor became visible, so show the volume controls.
|
||||||
animationFader = nil
|
optionsFader.animateIn()
|
||||||
for view in self.fadingViews {
|
|
||||||
animateInView(view)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func scanTargetViewWillHideOSMouseCursor(_ view: CSScanTargetView) {
|
internal func scanTargetViewWillHideOSMouseCursor(_ view: CSScanTargetView) {
|
||||||
// The OS mouse cursor will be hidden, so hide the volume controls.
|
// The OS mouse cursor will be hidden, so hide the volume controls.
|
||||||
let fadingViews = self.fadingViews
|
optionsFader.animateOut(delay: 0.0)
|
||||||
|
|
||||||
if !fadingViews[0].isHidden && fadingViews[0].layer?.animation(forKey: "opacity") == nil {
|
|
||||||
animationFader = ViewFader(views: fadingViews)
|
|
||||||
for view in self.fadingViews {
|
|
||||||
animateOutView(view, withDelay: 0.0, fader: animationFader!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Helpers for fading things in and out.
|
// MARK: - Helpers for fading things in and out.
|
||||||
|
|
||||||
// This class exists to provide a delegate to the generated CAAnimations
|
/// Maintains a list of views and offers in-and-out animations on those,
|
||||||
// that knows which views they refer to.
|
/// testing current state as necessary and otherwise coordinating with
|
||||||
|
/// CoreAnimation.
|
||||||
private class ViewFader: NSObject, CAAnimationDelegate {
|
private class ViewFader: NSObject, CAAnimationDelegate {
|
||||||
var views: [NSView]
|
private var views: [NSView]
|
||||||
|
private var opacity: Float = 0.0
|
||||||
|
|
||||||
init(views: [NSView]) {
|
init(views: [NSView]) {
|
||||||
self.views = views
|
self.views = views
|
||||||
}
|
|
||||||
|
|
||||||
func animationDidStart(_ anim: CAAnimation) {
|
|
||||||
for view in views {
|
|
||||||
view.layer!.opacity = 0.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func animationDidStop(_ animation: CAAnimation, finished: Bool) {
|
|
||||||
for view in views {
|
for view in views {
|
||||||
view.isHidden = true
|
view.isHidden = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private func animateInView(_ view: NSView) {
|
func animationDidStart(_ anim: CAAnimation) {
|
||||||
// Show immediately.
|
for view in views {
|
||||||
view.layer?.removeAllAnimations()
|
view.layer!.opacity = opacity
|
||||||
view.isHidden = false
|
}
|
||||||
view.layer?.opacity = 1.0
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private func animateOutView(_ view: NSView, withDelay delay: TimeInterval, fader: ViewFader) {
|
func animationDidStop(_ animation: CAAnimation, finished: Bool) {
|
||||||
let fadeAnimation = CABasicAnimation(keyPath: "opacity")
|
if finished {
|
||||||
fadeAnimation.beginTime = CACurrentMediaTime() + delay
|
for view in views {
|
||||||
fadeAnimation.fromValue = 1.0
|
view.isHidden = true
|
||||||
fadeAnimation.toValue = 0.0
|
}
|
||||||
fadeAnimation.duration = 0.2
|
}
|
||||||
fadeAnimation.delegate = fader
|
}
|
||||||
|
|
||||||
// The delegate will ensure the views stay hidden once animation is complete.
|
func animateIn() {
|
||||||
|
opacity = 1.0
|
||||||
|
|
||||||
view.layer?.removeAllAnimations()
|
for view in views {
|
||||||
view.layer!.add(fadeAnimation, forKey: "opacity")
|
view.layer?.removeAllAnimations()
|
||||||
|
view.isHidden = false
|
||||||
|
view.layer?.opacity = 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func animateOut(delay : TimeInterval) {
|
||||||
|
// Do nothing if already animating out.
|
||||||
|
if views[0].isHidden || views[0].layer?.animation(forKey: "opacity") != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
opacity = 0.0
|
||||||
|
for view in views {
|
||||||
|
let fadeAnimation = CABasicAnimation(keyPath: "opacity")
|
||||||
|
fadeAnimation.beginTime = CACurrentMediaTime() + delay
|
||||||
|
fadeAnimation.fromValue = 1.0
|
||||||
|
fadeAnimation.toValue = 0.0
|
||||||
|
fadeAnimation.duration = 0.2
|
||||||
|
fadeAnimation.delegate = self
|
||||||
|
|
||||||
|
view.layer?.removeAllAnimations()
|
||||||
|
view.layer!.add(fadeAnimation, forKey: "opacity")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Volume Control.
|
// MARK: - Volume Control.
|
||||||
|
Loading…
Reference in New Issue
Block a user