Commit 057e264e authored by Aral Balkan's avatar Aral Balkan

Added a dampner (and implemented cancellable delayed block execution) to the...

Added a dampner (and implemented cancellable delayed block execution) to the profile image component so that it doesn’t flood the image snapshot routine when the user is actively manipulating the image editor component.
parent fd92f38f
......@@ -26,33 +26,73 @@ func makeAccessibilityAnnouncement(message:String)
}
//
// Other
// General delay method that uses Grand Central Dispatch to execute a
// block after a specified number of seconds has elapsed. A cancellable block
// is returned, that you can cancel by calling and passing true for the cancel parameter.
//
// Based on CancelBlocks by Evgenii Rtishchev (https://github.com/katleta3000/CancelBlocks)
// and http://stackoverflow.com/questions/24034544/dispatch-after-gcd-in-swift
//
typealias dispatch_cancellable_block_t = (cancel:Bool) -> (Void)
func delay(delay:Double, closure:()->())
func delay(delay:Double, block:dispatch_block_t?) -> dispatch_cancellable_block_t?
{
//
// Run the passed closure after a given number of seconds.
// Based on: http://stackoverflow.com/questions/24034544/dispatch-after-gcd-in-swift
//
if delay < 0.0 {
if (block == nil)
{
return nil
}
if delay < 0.0
{
// Special case. If delay is negative, run the closure on the same stack frame.
// If you want to run the closure on the next stack frame, pass 0.0.
closure()
return
block!()
return nil
}
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
var originalBlock:dispatch_block_t? = block!
var cancellableBlock:dispatch_cancellable_block_t? = nil
var delayBlock:dispatch_cancellable_block_t =
{
(cancel:Bool) -> Void in
if ((!cancel) && (originalBlock != nil))
{
dispatch_async(dispatch_get_main_queue(), originalBlock!)
}
cancellableBlock = nil
originalBlock = nil
}
cancellableBlock = delayBlock
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_main_queue())
{
() -> Void in
if (cancellableBlock != nil)
{
cancellableBlock!(cancel: false)
}
}
return cancellableBlock
}
func dispatch_cancel_block_t(block:dispatch_cancellable_block_t?)
{
if (block != nil)
{
block!(cancel: true)
}
}
//
// Other
//
//
// Allows graceful overriding of any NSResponder subclass’s initialisation
......
......@@ -57,6 +57,8 @@ class ProfileImageComponentViewController: NSViewController, NSComboBoxDataSourc
var faces:[CIFaceFeature]
var cancellableProfileImageUpdateBlock:dispatch_cancellable_block_t?
//
// Sets the Profile Image Picker view editable state
// (and animates gracefully between the states).
......@@ -653,8 +655,14 @@ class ProfileImageComponentViewController: NSViewController, NSComboBoxDataSourc
// Post a notification (mainly for the benefit of the control panel for debugging).
NSNotificationCenter.defaultCenter().send(ProfileImageComponentNotification.named(.ProfileImageBoundsDidChange), from: self, with: userInfo as [NSObject : AnyObject])
// Update the image whenever its bounds change.
self.croppedImage()
//
// Update the image whenever its bounds change (after a cancellable delay, so we’re not firing it too quickly).
//
cancellableProfileImageUpdateBlock?(cancel:true)
cancellableProfileImageUpdateBlock = delay(0.3)
{
self.croppedImage()
}
}
//
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment