Revision: 2632 http://skim-app.svn.sourceforge.net/skim-app/?rev=2632&view=rev Author: hofman Date: 2007-08-09 07:36:05 -0700 (Thu, 09 Aug 2007)
Log Message: ----------- Add a zoom option to the popup to automatically adjust the scale factor to fit the currently displayed rect. Modified Paths: -------------- trunk/BDSKZoomablePDFView.h trunk/BDSKZoomablePDFView.m Modified: trunk/BDSKZoomablePDFView.h =================================================================== --- trunk/BDSKZoomablePDFView.h 2007-08-09 11:40:55 UTC (rev 2631) +++ trunk/BDSKZoomablePDFView.h 2007-08-09 14:36:05 UTC (rev 2632) @@ -42,13 +42,21 @@ @interface BDSKZoomablePDFView : PDFView { NSPopUpButton *scalePopUpButton; + PDFPage *page; + NSRect fitRect; + BOOL fits; } +- (BOOL)fits; +- (void)setFits:(BOOL)newFits; +- (void)setFits:(BOOL)newFits adjustPopup:(BOOL)flag; +- (void)setAutoScales:(BOOL)newAuto adjustPopup:(BOOL)flag; - (void)setScaleFactor:(float)factor adjustPopup:(BOOL)flag; - (void)scalePopUpAction:(id)sender; - (NSScrollView *)scrollView; - (void)layoutScrollView; - (void)setScrollerSize:(NSControlSize)controlSize; - (void)dragWithEvent:(NSEvent *)theEvent; +- (void)handlePDFViewFrameChangedNotification:(NSNotification *)notification; @end Modified: trunk/BDSKZoomablePDFView.m =================================================================== --- trunk/BDSKZoomablePDFView.m 2007-08-09 11:40:55 UTC (rev 2631) +++ trunk/BDSKZoomablePDFView.m 2007-08-09 14:36:05 UTC (rev 2632) @@ -48,6 +48,7 @@ @implementation BDSKZoomablePDFView /* For genstrings: + NSLocalizedStringFromTable(@"Fit", @"ZoomValues", @"Zoom popup entry") NSLocalizedStringFromTable(@"Auto", @"ZoomValues", @"Zoom popup entry") NSLocalizedStringFromTable(@"10%", @"ZoomValues", @"Zoom popup entry") NSLocalizedStringFromTable(@"25%", @"ZoomValues", @"Zoom popup entry") @@ -59,12 +60,43 @@ NSLocalizedStringFromTable(@"400%", @"ZoomValues", @"Zoom popup entry") NSLocalizedStringFromTable(@"800%", @"ZoomValues", @"Zoom popup entry") */ -static NSString *BDSKDefaultScaleMenuLabels[] = {/* @"Set...", */ @"Auto", @"10%", @"25%", @"50%", @"75%", @"100%", @"128%", @"150%", @"200%", @"400%", @"800%"}; -static float BDSKDefaultScaleMenuFactors[] = {/* 0.0, */ 0, 0.1, 0.25, 0.5, 0.75, 1.0, 1.28, 1.5, 2.0, 4.0, 8.0}; +static NSString *BDSKDefaultScaleMenuLabels[] = {/* @"Set...", */ @"Fit", @"Auto", @"10%", @"25%", @"50%", @"75%", @"100%", @"128%", @"150%", @"200%", @"400%", @"800%"}; +static float BDSKDefaultScaleMenuFactors[] = {/* 0.0, */ -1, 0, 0.1, 0.25, 0.5, 0.75, 1.0, 1.28, 1.5, 2.0, 4.0, 8.0}; static float BDSKScaleMenuFontSize = 11.0; #pragma mark Popup button +- (id)initWithFrame:(NSRect)frameRect { + if (self = [super initWithFrame:frameRect]) { + scalePopUpButton = nil; + page = nil; + fitRect = NSZeroRect; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePDFViewFrameChangedNotification:) + name:NSViewFrameDidChangeNotification object:self]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePDFViewFrameChangedNotification:) + name:NSViewBoundsDidChangeNotification object:self]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)decoder { + if (self = [super initWithCoder:decoder]) { + scalePopUpButton = nil; + page = nil; + fitRect = NSZeroRect; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePDFViewFrameChangedNotification:) + name:NSViewFrameDidChangeNotification object:self]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePDFViewFrameChangedNotification:) + name:NSViewBoundsDidChangeNotification object:self]; + } + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [super dealloc]; +} + - (void)makeScalePopUpButton { if (scalePopUpButton == nil) { @@ -130,14 +162,55 @@ } } +- (void)handlePDFViewFrameChangedNotification:(NSNotification *)notification { + if (fits) { + NSView *clipView = [[[self documentView] enclosingScrollView] contentView]; + NSRect rect = [self convertRect:[clipView visibleRect] fromView:clipView]; + BOOL scaleWidth = NSWidth(rect) / NSHeight(rect) < NSWidth(fitRect) / NSHeight(fitRect); + float factor = scaleWidth ? NSWidth(rect) / NSWidth(fitRect) : NSHeight(rect) / NSHeight(fitRect); + NSRect viewRect = scaleWidth ? NSInsetRect(fitRect, 0.0, 0.5 * (NSHeight(fitRect) - NSHeight(rect) / factor)) : NSInsetRect(fitRect, 0.5 * (NSWidth(fitRect) - NSWidth(rect) / factor), 0.0); + [super setScaleFactor:factor]; + viewRect = [self convertRect:[self convertRect:viewRect fromPage:page] toView:[self documentView]]; + [[self documentView] scrollRectToVisible:viewRect]; + } +} + - (void)scalePopUpAction:(id)sender { + int index = [sender indexOfSelectedItem]; NSNumber *selectedFactorObject = [[sender selectedCell] representedObject]; - if(!selectedFactorObject) - [super setAutoScales:YES]; - else + if(index == 0) + [self setFits:YES adjustPopup:NO]; + else if(index == 1) + [self setAutoScales:YES adjustPopup:NO]; + else if(selectedFactorObject) [self setScaleFactor:[selectedFactorObject floatValue] adjustPopup:NO]; } +- (BOOL)fits { + return fits; +} + +- (void)setFits:(BOOL)newFits { + [self setFits:newFits adjustPopup:YES]; +} + +- (void)setFits:(BOOL)newFits adjustPopup:(BOOL)flag { + if (fits != newFits) { + fits = newFits; + if (fits) { + NSView *clipView = [[[self documentView] enclosingScrollView] contentView]; + page = [self currentPage]; + fitRect = [self convertRect:[self convertRect:[clipView visibleRect] fromView:clipView] toPage:page]; + [self setAutoScales:NO adjustPopup:NO]; + if (flag) + [scalePopUpButton selectItemAtIndex:0]; + } else { + page = nil; + fitRect = NSZeroRect; + } + } +} + - (void)setScaleFactor:(float)newScaleFactor { [self setScaleFactor:newScaleFactor adjustPopup:YES]; } @@ -145,10 +218,12 @@ - (void)setScaleFactor:(float)newScaleFactor adjustPopup:(BOOL)flag { if (flag) { - if (newScaleFactor < 0.01) { + if (newScaleFactor < -0.01) { + newScaleFactor = -1.0; + } else if (newScaleFactor < 0.01) { newScaleFactor = 0.0; } else { - unsigned cnt = 1, numberOfDefaultItems = (sizeof(BDSKDefaultScaleMenuFactors) / sizeof(float)); + unsigned cnt = 2, numberOfDefaultItems = (sizeof(BDSKDefaultScaleMenuFactors) / sizeof(float)); // We only work with some preset zoom values, so choose one of the appropriate values while (cnt < numberOfDefaultItems - 1 && newScaleFactor > 0.5 * (BDSKDefaultScaleMenuFactors[cnt] + BDSKDefaultScaleMenuFactors[cnt + 1])) cnt++; @@ -157,24 +232,40 @@ } } + if(newScaleFactor < -0.01) + [self setFits:YES]; if(newScaleFactor < 0.01) [self setAutoScales:YES]; - else + else{ + [self setFits:NO adjustPopup:NO]; [super setScaleFactor:newScaleFactor]; + } } - (void)setAutoScales:(BOOL)newAuto { + [self setAutoScales:newAuto adjustPopup:YES]; +} + +- (void)setAutoScales:(BOOL)newAuto adjustPopup:(BOOL)flag { + if (newAuto) + [self setFits:NO adjustPopup:NO]; + [super setAutoScales:newAuto]; - if(newAuto) - [scalePopUpButton selectItemAtIndex:0]; + if(newAuto && flag) + [scalePopUpButton selectItemAtIndex:1]; } - (IBAction)zoomIn:(id)sender{ - if([self autoScales]){ + if([self fits]){ [super zoomIn:sender]; + NSView *clipView = [[[self documentView] enclosingScrollView] contentView]; + page = [self currentPage]; + fitRect = [self convertRect:[self convertRect:[clipView visibleRect] fromView:clipView] toPage:page]; + }else if([self autoScales]){ + [super zoomIn:sender]; }else{ - int cnt = 0, numberOfDefaultItems = (sizeof(BDSKDefaultScaleMenuFactors) / sizeof(float)); + int cnt = 1, numberOfDefaultItems = (sizeof(BDSKDefaultScaleMenuFactors) / sizeof(float)); float scaleFactor = [self scaleFactor]; // We only work with some preset zoom values, so choose one of the appropriate values (Fudge a little for floating point == to work) @@ -186,16 +277,21 @@ } - (IBAction)zoomOut:(id)sender{ - if([self autoScales]){ + if([self fits]){ [super zoomOut:sender]; + NSView *clipView = [[[self documentView] enclosingScrollView] contentView]; + page = [self currentPage]; + fitRect = [self convertRect:[self convertRect:[clipView visibleRect] fromView:clipView] toPage:page]; + }else if([self autoScales]){ + [super zoomOut:sender]; }else{ - int cnt = 0, numberOfDefaultItems = (sizeof(BDSKDefaultScaleMenuFactors) / sizeof(float)); + int cnt = 1, numberOfDefaultItems = (sizeof(BDSKDefaultScaleMenuFactors) / sizeof(float)); float scaleFactor = [self scaleFactor]; // We only work with some preset zoom values, so choose one of the appropriate values (Fudge a little for floating point == to work) while (cnt < numberOfDefaultItems && scaleFactor * .99 > BDSKDefaultScaleMenuFactors[cnt]) cnt++; cnt--; - if (cnt < 0) cnt++; + if (cnt < 1) cnt++; [self setScaleFactor:BDSKDefaultScaleMenuFactors[cnt]]; } } @@ -205,7 +301,7 @@ return NO; if([self autoScales]) return YES; - unsigned cnt = 0, numberOfDefaultItems = (sizeof(BDSKDefaultScaleMenuFactors) / sizeof(float)); + unsigned cnt = 1, numberOfDefaultItems = (sizeof(BDSKDefaultScaleMenuFactors) / sizeof(float)); float scaleFactor = [self scaleFactor]; // We only work with some preset zoom values, so choose one of the appropriate values (Fudge a little for floating point == to work) while (cnt < numberOfDefaultItems && scaleFactor * .99 > BDSKDefaultScaleMenuFactors[cnt]) cnt++; @@ -355,6 +451,12 @@ break; } // end of switch (event type) } // end of mouse-tracking loop + + if ([self fits]) { + NSView *clipView = [[[self documentView] enclosingScrollView] contentView]; + page = [self currentPage]; + fitRect = [self convertRect:[self convertRect:[clipView visibleRect] fromView:clipView] toPage:page]; + } } @end This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ Skim-app-commit mailing list Skim-app-commit@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/skim-app-commit