diff --git a/ShadowsocksX-NG/PreferencesWindowController.swift b/ShadowsocksX-NG/PreferencesWindowController.swift index 6cff2ce..d15a335 100644 --- a/ShadowsocksX-NG/PreferencesWindowController.swift +++ b/ShadowsocksX-NG/PreferencesWindowController.swift @@ -95,6 +95,7 @@ class PreferencesWindowController: NSWindowController if editingProfile != nil { if !editingProfile.isValid() { // TODO Shake window? + shakeWindows() return } } @@ -293,4 +294,27 @@ class PreferencesWindowController: NSWindowController } } } + + func shakeWindows(){ + let numberOfShakes:Int = 8 + let durationOfShake:Float = 0.5 + let vigourOfShake:Float = 0.05 + + let frame:CGRect = (window?.frame)! + let shakeAnimation = CAKeyframeAnimation() + + let shakePath = CGPathCreateMutable() + CGPathMoveToPoint(shakePath, nil, NSMinX(frame), NSMinY(frame)) + + for _ in 1...numberOfShakes{ + CGPathAddLineToPoint(shakePath, nil, NSMinX(frame) - frame.size.width * CGFloat(vigourOfShake), NSMinY(frame)) + CGPathAddLineToPoint(shakePath, nil, NSMinX(frame) + frame.size.width * CGFloat(vigourOfShake), NSMinY(frame)) + } + + CGPathCloseSubpath(shakePath) + shakeAnimation.path = shakePath + shakeAnimation.duration = CFTimeInterval(durationOfShake) + window?.animations = ["frameOrigin":shakeAnimation] + window?.animator().setFrameOrigin(window!.frame.origin) + } }