From a801860f90469fbe489d8b6bfd5b490eea3d61bf Mon Sep 17 00:00:00 2001 From: Mike Fellows Date: Tue, 18 Jan 2011 22:51:04 -0800 Subject: [PATCH] Move the functionality from CPStepper's _CPContinuousButton object into CPButton so any CPButton can be made continuous --- AppKit/CPButton.j | 67 +++++++++++++++++++++++++++- AppKit/CPStepper.j | 108 +++------------------------------------------ 2 files changed, 71 insertions(+), 104 deletions(-) diff --git a/AppKit/CPButton.j b/AppKit/CPButton.j index 672991207..40b5cb73c 100644 --- a/AppKit/CPButton.j +++ b/AppKit/CPButton.j @@ -106,6 +106,11 @@ CPButtonImageOffset = 3.0; CPString _keyEquivalent; unsigned _keyEquivalentModifierMask; + + CPTimer _continuousDelayTimer; + CPTimer _continuousTimer; + float _periodicDelay; + float _periodicInterval; } + (id)buttonWithTitle:(CPString)aTitle @@ -159,6 +164,10 @@ CPButtonImageOffset = 3.0; [self setBezelStyle:CPRoundRectBezelStyle]; [self setBordered:YES]; + + // Continuous button defaults. + _periodicInterval = 0.05; + _periodicDelay = 0.5; } return self; @@ -450,6 +459,34 @@ CPButtonImageOffset = 3.0; return _imageDimsWhenDisabled; } +- (void)setPeriodicDelay:(float)aDelay interval:(float)anInterval +{ + _periodicDelay = aDelay; + _periodicInterval = anInterval; +} + +- (void)mouseDown:(CPEvent)anEvent +{ + if ([self isContinuous]) + { + _continuousDelayTimer = [CPTimer scheduledTimerWithTimeInterval:_periodicDelay callback: function() + { + if (!_continuousTimer) + _continuousTimer = [CPTimer scheduledTimerWithTimeInterval:_periodicInterval target:self selector:@selector(onContinousEvent:) userInfo:anEvent repeats:YES]; + } + + repeats:NO]; + } + + [super mouseDown:anEvent]; +} + +- (void)onContinousEvent:(CPTimer)aTimer +{ + if (_target && _action && [_target respondsToSelector:_action]) + [_target performSelector:_action withObject:self]; +} + - (BOOL)startTrackingAt:(CGPoint)aPoint { [self highlight:YES]; @@ -460,6 +497,7 @@ CPButtonImageOffset = 3.0; - (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp { [self highlight:NO]; + [self invalidateTimers]; [super stopTracking:lastPoint at:aPoint mouseIsUp:mouseIsUp]; @@ -467,6 +505,21 @@ CPButtonImageOffset = 3.0; [self setNextState]; } +- (void)invalidateTimers +{ + if (_continuousTimer) + { + [_continuousTimer invalidate]; + _continuousTimer = nil; + } + + if (_continuousDelayTimer) + { + [_continuousDelayTimer invalidate]; + _continuousDelayTimer = nil; + } +} + - (CGRect)contentRectForBounds:(CGRect)bounds { var contentInset = [self currentValueForThemeAttribute:@"content-inset"]; @@ -719,7 +772,9 @@ var CPButtonImageKey = @"CPButtonImageKey", CPButtonImageDimsWhenDisabledKey = @"CPButtonImageDimsWhenDisabledKey", CPButtonImagePositionKey = @"CPButtonImagePositionKey", CPButtonKeyEquivalentKey = @"CPButtonKeyEquivalentKey", - CPButtonKeyEquivalentMaskKey = @"CPButtonKeyEquivalentMaskKey"; + CPButtonKeyEquivalentMaskKey = @"CPButtonKeyEquivalentMaskKey", + CPButtonPeriodicDelayKey = @"CPButtonPeriodicDelayKey", + CPButtonPeriodicIntervalKey = @"CPButtonPeriodicIntervalKey"; @implementation CPButton (CPCoding) @@ -749,6 +804,12 @@ var CPButtonImageKey = @"CPButtonImageKey", if ([aCoder containsValueForKey:CPButtonKeyEquivalentKey]) [self setKeyEquivalent:CFData.decodeBase64ToUtf16String([aCoder decodeObjectForKey:CPButtonKeyEquivalentKey])]; + if ([aCoder containsValueForKey:CPButtonPeriodicDelayKey]) + _periodicDelay = [aCoder decodeObjectForKey:CPButtonPeriodicDelayKey]; + + if ([aCoder containsValueForKey:CPButtonPeriodicIntervalKey]) + _periodicInterval = [aCoder decodeObjectForKey:CPButtonPeriodicIntervalKey]; + _keyEquivalentModifierMask = [aCoder decodeIntForKey:CPButtonKeyEquivalentMaskKey]; [self setNeedsLayout]; @@ -765,6 +826,7 @@ var CPButtonImageKey = @"CPButtonImageKey", - (void)encodeWithCoder:(CPCoder)aCoder { [super encodeWithCoder:aCoder]; + [self invalidateTimers]; [aCoder encodeObject:_title forKey:CPButtonTitleKey]; [aCoder encodeObject:_alternateTitle forKey:CPButtonAlternateTitleKey]; @@ -778,6 +840,9 @@ var CPButtonImageKey = @"CPButtonImageKey", [aCoder encodeObject:CFData.encodeBase64Utf16String(_keyEquivalent) forKey:CPButtonKeyEquivalentKey]; [aCoder encodeInt:_keyEquivalentModifierMask forKey:CPButtonKeyEquivalentMaskKey]; + + [aCoder encodeObject:_periodicDelay forKey:CPButtonPeriodicDelayKey]; + [aCoder encodeObject:_periodicInterval forKey:CPButtonPeriodicIntervalKey]; } @end diff --git a/AppKit/CPStepper.j b/AppKit/CPStepper.j index ba2b28b07..7034e0004 100644 --- a/AppKit/CPStepper.j +++ b/AppKit/CPStepper.j @@ -38,8 +38,8 @@ var CPStepperButtonsSize = CPSizeMake(19, 13); int _maxValue @accessors(property=maxValue); int _minValue @accessors(property=minValue); - _CPContinuousButton _buttonDown; - _CPContinuousButton _buttonUp; + CPButton _buttonDown; + CPButton _buttonUp; } #pragma mark - @@ -87,14 +87,14 @@ var CPStepperButtonsSize = CPSizeMake(19, 13); [self setDoubleValue:0.0]; - _buttonUp = [[_CPContinuousButton alloc] initWithFrame:CPRectMake(aFrame.size.width - CPStepperButtonsSize.width, 0, CPStepperButtonsSize.width, CPStepperButtonsSize.height)]; + _buttonUp = [[CPButton alloc] initWithFrame:CPRectMake(aFrame.size.width - CPStepperButtonsSize.width, 0, CPStepperButtonsSize.width, CPStepperButtonsSize.height)]; [_buttonUp setContinuous:YES]; [_buttonUp setTarget:self]; [_buttonUp setAction:@selector(_buttonDidClick:)]; [_buttonUp setAutoresizingMask:CPViewNotSizable]; [self addSubview:_buttonUp]; - _buttonDown = [[_CPContinuousButton alloc] initWithFrame:CPRectMake(aFrame.size.width - CPStepperButtonsSize.width, CPStepperButtonsSize.height, CPStepperButtonsSize.width, CPStepperButtonsSize.height - 1)]; + _buttonDown = [[CPButton alloc] initWithFrame:CPRectMake(aFrame.size.width - CPStepperButtonsSize.width, CPStepperButtonsSize.height, CPStepperButtonsSize.width, CPStepperButtonsSize.height - 1)]; [_buttonDown setContinuous:YES]; [_buttonDown setTarget:self]; [_buttonDown setAction:@selector(_buttonDidClick:)]; @@ -152,7 +152,7 @@ var CPStepperButtonsSize = CPSizeMake(19, 13); } /*! set the current value of the stepper - @param aValue a float contaning the value + @param aValue a float containing the value */ - (void)setDoubleValue:(float)aValue { @@ -244,101 +244,3 @@ var CPStepperButtonsSize = CPSizeMake(19, 13); } @end - - -/*! This is a subclass of CPButton that allows to send continuous action. - This may should be include in CPButton.. -*/ -@implementation _CPContinuousButton : CPButton -{ - CPTimer _continuousDelayTimer; - CPTimer _continuousTimer; - float _periodicDelay; - float _periodicInterval; -} - -- (void)initWithFrame:(CGRect)aFrame -{ - if (self = [super initWithFrame:aFrame]) - { - _periodicInterval = 0.05; - _periodicDelay = 0.5; - } - - return self; -} - -- (void)setPeriodicDelay:(float)aDelay interval:(float)anInterval -{ - _periodicDelay = aDelay; - _periodicInterval = anInterval; -} - -- (void)mouseDown:(CPEvent)anEvent -{ - if ([self isContinuous]) - { - _continuousDelayTimer = [CPTimer scheduledTimerWithTimeInterval:_periodicDelay callback: function() - { - if (!_continuousTimer) - _continuousTimer = [CPTimer scheduledTimerWithTimeInterval:_periodicInterval target:self selector:@selector(onContinousEvent:) userInfo:anEvent repeats:YES]; - } - - repeats:NO]; - } - - [super mouseDown:anEvent]; -} - -- (void)onContinousEvent:(CPTimer)aTimer -{ - if (_target && _action && [_target respondsToSelector:_action]) - [_target performSelector:_action withObject:self]; -} - -- (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp -{ - [self invalidateTimers]; - [super stopTracking:lastPoint at:aPoint mouseIsUp:mouseIsUp]; -} - -- (void)invalidateTimers -{ - if (_continuousTimer) - { - [_continuousTimer invalidate]; - _continuousTimer = nil; - } - - if (_continuousDelayTimer) - { - [_continuousDelayTimer invalidate]; - _continuousDelayTimer = nil; - } -} - -@end - - - -@implementation _CPContinuousButton (CPCodingCompliance) - -- (id)initWithCoder:(CPCoder)aCoder -{ - if (self = [super initWithCoder:aCoder]) - { - _periodicDelay = [aCoder decodeObjectForKey:@"_periodicDelay"]; - _periodicInterval = [aCoder decodeObjectForKey:@"_periodicInterval"]; - } - return self; -} - -- (void)encodeWithCoder:(CPCoder)aCoder -{ - [super encodeWithCoder:aCoder]; - - [self invalidateTimers]; - [aCoder encodeObject:_periodicDelay forKey:@"_periodicDelay"]; - [aCoder encodeObject:_periodicInterval forKey:@"_periodicInterval"]; -} -@end