Permalink
Browse files

updated

  • Loading branch information...
1 parent c57b1a2 commit f999bfbe7db362794a137641979fb9f6385c0674 @ndbroadbent committed Nov 9, 2010
Showing with 75 additions and 21 deletions.
  1. +10 −7 dev-notes.txt
  2. +65 −14 src/QSP.m
View
@@ -14,13 +14,16 @@ Accelerometer Reference Points (ABS):
medium scroll backwards : 0.2 <=> 0.3
slow scroll backwards : 0.3 <=> 0.45
resting (still) : 0.45 <=> 0.55
- slow scroll : 0.55 <=> 0.7
- medium scroll : 0.7 <=> 0.8
+ slow scroll : 0.55 <=> 0.65
+ medium scroll : 0.65 <=> 0.8
fast scroll : 0.8 <=> 0.9
- scroll one page per second : > 0.9
+ very fast scroll : > 0.9
-Scrolling Speeds:
+Scrolling Speeds (n-scale per step):
- slow: 5 px/s
- medium: 15 px/s
- fast: 35 px/s
+ slow (reading): 0.1
+ medium: 0.3
+ medium scan: 0.5
+ medium-fast scan: 1.0
+ fast: 3.0
+ super-fast: 5.0
View
@@ -808,7 +808,7 @@ -(void)togglePager {
#pragma mark -
-@interface QSScrollbar : UIView {
+@interface QSScrollbar : UIView <UIAccelerometerDelegate> {
CGSize scale;
QSAbstractScroller* abstractScroller;
CGRect relativeFrame, visualRelFrame, savedVisualRelFrame;
@@ -822,8 +822,12 @@ @interface QSScrollbar : UIView {
NSTimer* tapTimer;
int tapCount;
BOOL isTiltActivated;
+ NSTimer* tiltScrollTimer;
+ float tiltScrollSpeed; // n-scale steps per second
+ UIAccelerometer* accelerometer;
}
@property(assign,nonatomic) CGSize scale;
+-(float)accelToTiltSpeed: (float)accel minRange:(float)minRange maxRange:(float)maxRange minOutput:(float)minOutput maxOutput:(float)maxOutput invert:(BOOL)invert;
@end
@implementation QSScrollbar
@synthesize scale;
@@ -845,7 +849,7 @@ -(void)shiftRelativeFrameVisuallyBy:(CGSize)shift {
visualRelFrame.origin.y += shift.height;
CGPoint oldOrigin = relativeFrame.origin;
- relativeFrame.origin = visualToActualPoint(visualRelFrame.origin, relativeFrame.size, self.bounds.size, handleSize);
+ relativeFrame.origin = visualToActualPoint(visualRelFrame.origin, relativeFrame.size, self.bounds.size, minHandleDisplaySize);
if (isVertical)
relativeFrame.origin.x = oldOrigin.x;
else
@@ -864,6 +868,7 @@ -(id)initWithFrame:(CGRect)frame abstractScroller:(QSAbstractScroller*)absScr ve
tilt_button = tltBtn;
tilt_button_down = tltBtnDown;
tapCount = 0;
+ tiltScrollSpeed = 0.0;
isTiltActivated = NO;
self.autoresizingMask = vert ? (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight) : (UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth);
self.contentMode = UIViewContentModeRedraw;
@@ -992,44 +997,90 @@ -(void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
}
if (isTiltActivated) {
+ // ------- Turn off tilt scrolling -------
isTiltActivated = NO;
- [abstractScroller enableFading];
-
- // ------- Turn off tilt scrolling here -------
+ [abstractScroller enableFading]; // Let our scrollbars fade away
+ [tiltScrollTimer invalidate];
+ [tiltScrollTimer release];
+ tiltScrollTimer = nil;
+ accelerometer = nil;
} else {
tapCount += 1;
if (tapCount == 2) {
- tapCount = 0;
// Scrollbar was double-tapped.
+ // ------- Turn on tilt scrolling -------
+ tapCount = 0;
isTiltActivated = YES;
- [abstractScroller disableFading];
-
-
- // ------- Turn on tilt scrolling here -------
-
+ [abstractScroller disableFading]; // Make sure our scrollbars don't fade away.
+ // Initialize accelerometer
+ accelerometer = [UIAccelerometer sharedAccelerometer];
+ accelerometer.updateInterval = .1;
+ accelerometer.delegate = self;
+ // Initialize timer for scrolling speed
+ tiltScrollTimer = [[NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(fireTiltScrollStep) userInfo:nil repeats:YES] retain];
} else {
- tapTimer = [[NSTimer scheduledTimerWithTimeInterval:0.7 target:self selector:@selector(fireTapReset) userInfo:nil repeats:YES] retain];
+ // If this is only the first tap, start a timer that will reset the tap counter after a delay.
+ tapTimer = [[NSTimer scheduledTimerWithTimeInterval:0.7 target:self selector:@selector(fireTapReset) userInfo:nil repeats:NO] retain];
}
}
}
[self setNeedsDisplay];
}
+-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
+ [self touchesEnded:touches withEvent:event];
+}
-(void)fireTapReset {
tapCount = 0;
}
--(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
- [self touchesEnded:touches withEvent:event];
+// Shared accelerometer calls this function at a specified interval, to update its readings.
+- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
+ // Set the tilt scrolling speed based on the accelerometer reading.
+ float ac = ABS(acceleration.y);
+ if (ac > 0.65) {
+ // 0.4 up to 8.0, between 0.65 and 1.0
+ tiltScrollSpeed = [self accelToTiltSpeed: ac minRange:0.65 maxRange:1.0 minOutput:0.4 maxOutput:8.0 invert:NO];
+ } else if (ac > 0.55) {
+ // 0.1 up to 0.4, between 0.55 and 0.65
+ tiltScrollSpeed = [self accelToTiltSpeed: ac minRange:0.55 maxRange:0.65 minOutput:0.1 maxOutput:0.4 invert:NO];
+ } else if (ac > 0.45) {
+ // Not moving
+ tiltScrollSpeed = 0;
+ } else {
+ // -0.1 up to -8.0, between 0.0 and 0.45 (this is 'inverted' since it speeds up as it gets smaller.)
+ tiltScrollSpeed = -1.0 * [self accelToTiltSpeed: ac minRange:0.0 maxRange:0.45 minOutput:0.1 maxOutput:8.0 invert:YES];
+ }
+}
+
+-(float)accelToTiltSpeed: (float)accel minRange:(float)minRange maxRange:(float)maxRange minOutput:(float)minOutput maxOutput:(float)maxOutput invert:(BOOL)invert {
+ return ((invert?(maxRange - accel):(accel - minRange))/(maxRange - minRange) * (maxOutput - minOutput)) + minOutput;
}
+
+// Each time the tiltScrollTimer is fired, step 1 pixel in a direction based on the scroll speed's sign.
+-(void)fireTiltScrollStep {
+ savedVisualRelFrame = visualRelFrame;
+ CGSize delta = CGSizeZero;
+ if (isVertical) {
+ // This calculation means that we can move the scrollbar at a given fixed rate, but relative to the frame size.
+ delta.height = (relativeFrame.size.height / visualRelFrame.size.height) * tiltScrollSpeed;
+ } else {
+ delta.width = (relativeFrame.size.width / visualRelFrame.size.width) * tiltScrollSpeed;
+ }
+ [self shiftRelativeFrameVisuallyBy:delta];
+ savedVisualRelFrame = visualRelFrame;
+}
+
-(void)dealloc {
[autoShiftTimer invalidate];
[autoShiftTimer release];
[tapTimer invalidate];
[tapTimer release];
+ [tiltScrollTimer invalidate];
+ [tiltScrollTimer release];
[super dealloc];
}
@end

0 comments on commit f999bfb

Please sign in to comment.