diff options
author | Damiano Galassi <[email protected]> | 2019-10-05 19:00:30 +0200 |
---|---|---|
committer | Damiano Galassi <[email protected]> | 2019-10-05 19:00:30 +0200 |
commit | 4238775818207edef7f303dabf99684f5542bc53 (patch) | |
tree | 0fc0b4a659abd329f394a92c31adcfcf6085cefe /macosx/HBPreviewView.m | |
parent | b8fc24a311d3f0163fd39d758d54096f37dbb8b3 (diff) |
Improve preview window sizing.
Diffstat (limited to 'macosx/HBPreviewView.m')
-rw-r--r-- | macosx/HBPreviewView.m | 163 |
1 files changed, 67 insertions, 96 deletions
diff --git a/macosx/HBPreviewView.m b/macosx/HBPreviewView.m index 7f5b81e30..753fd09f4 100644 --- a/macosx/HBPreviewView.m +++ b/macosx/HBPreviewView.m @@ -5,6 +5,7 @@ It may be used under the terms of the GNU General Public License. */ #import "HBPreviewView.h" +#import <QuartzCore/QuartzCore.h> // the white border around the preview image #define BORDER_SIZE 2.0 @@ -14,11 +15,6 @@ @property (nonatomic) CALayer *backLayer; @property (nonatomic) CALayer *pictureLayer; -@property (nonatomic, readwrite) CGFloat scale; -@property (nonatomic, readwrite) NSRect pictureFrame; - -@property (nonatomic, readwrite) CGFloat scaleFactor; - @end @implementation HBPreviewView @@ -85,17 +81,14 @@ _pictureLayer.hidden = YES; _backLayer.hidden = YES; - _showBorder = YES; - _scale = 1; - _pictureFrame = _pictureLayer.frame; } - (void)viewDidChangeBackingProperties { if (self.window) { - self.scaleFactor = self.window.backingScaleFactor; + self.needsLayout = YES; } } @@ -109,20 +102,20 @@ self.pictureLayer.hidden = hidden ; self.backLayer.hidden = hidden || !self.showBorder; - [self _updatePreviewLayout]; + self.needsLayout = YES; } - (void)setFitToView:(BOOL)fitToView { _fitToView = fitToView; - [self _updatePreviewLayout]; + self.needsLayout = YES; } - (void)setShowBorder:(BOOL)showBorder { _showBorder = showBorder; self.backLayer.hidden = !showBorder; - [self _updatePreviewLayout]; + self.needsLayout = YES; } - (void)setShowShadow:(BOOL)showShadow @@ -130,16 +123,27 @@ _backLayer.shadowOpacity = showShadow ? 0.5f : 0; } -- (void)setFrame:(NSRect)newRect { - // A change in size has required the view to be invalidated. - if ([self inLiveResize]) { - [super setFrame:newRect]; +- (CGFloat)scale +{ + if (self.image) + { + NSSize imageSize = NSMakeSize(CGImageGetWidth(self.image), CGImageGetHeight(self.image)); + CGFloat backingScaleFactor = self.window.backingScaleFactor; + CGFloat borderSize = self.showBorder ? BORDER_SIZE : 0; + + NSSize imageScaledSize = [self imageScaledSize:imageSize toFit:self.frame.size borderSize:borderSize scaleFactor:self.window.backingScaleFactor]; + + return (imageScaledSize.width - borderSize * 2) / imageSize.width * backingScaleFactor; } - else { - [super setFrame:newRect]; + else + { + return 1; } +} - [self _updatePreviewLayout]; +- (CGRect)pictureFrame +{ + return self.pictureLayer.frame; } - (NSSize)scaledSize:(NSSize)source toFit:(NSSize)destination @@ -165,91 +169,68 @@ return result; } -/** - * Updates the sublayers layout. - */ -- (void)_updatePreviewLayout +- (NSSize)imageScaledSize:(NSSize)source toFit:(NSSize)destination borderSize:(CGFloat)borderSize scaleFactor:(CGFloat)scaleFactor +{ + // HiDPI mode usually display everything + // with double pixel count, but we don't + // want to double the size of the video + NSSize scaledSource = NSMakeSize(source.width / scaleFactor, source.height / scaleFactor); + + scaledSource.width += borderSize * 2; + scaledSource.height += borderSize * 2; + + if (self.fitToView == YES || scaledSource.width > destination.width || scaledSource.height > destination.height) + { + // If the image is larger then the view or if we are in Fit to View mode, scale the image + scaledSource = [self scaledSize:source toFit:destination]; + } + + return scaledSource; +} + +- (void)layout { // Set the picture size display fields below the Preview Picture NSSize imageSize = NSMakeSize(CGImageGetWidth(self.image), CGImageGetHeight(self.image)); - CGFloat backingScaleFactor = 1.0; if (imageSize.width > 0 && imageSize.height > 0) { - backingScaleFactor = self.scaleFactor; - - // HiDPI mode usually display everything - // with double pixel count, but we don't - // want to double the size of the video - NSSize imageScaledSize = NSMakeSize(imageSize.width / backingScaleFactor, imageSize.height / backingScaleFactor); + CGFloat borderSize = self.showBorder ? BORDER_SIZE : 0; NSSize frameSize = self.frame.size; + + NSSize imageScaledSize = [self imageScaledSize:imageSize + toFit:frameSize + borderSize:borderSize + scaleFactor:self.window.backingScaleFactor]; + + [CATransaction begin]; + CATransaction.disableActions = YES; - if (self.showBorder == YES) - { - frameSize.width -= BORDER_SIZE * 2; - frameSize.height -= BORDER_SIZE * 2; - } - - if (self.fitToView == YES) - { - // We are in Fit to View mode so, we have to get the ratio for height and width against the window - // size so we can scale from there. - imageScaledSize = [self scaledSize:imageScaledSize toFit:frameSize]; - } - else if (imageScaledSize.width > frameSize.width || imageScaledSize.height > frameSize.height) - { - // If the image is larger then the view, scale the image - imageScaledSize = [self scaledSize:imageScaledSize toFit:frameSize]; - } - - [NSAnimationContext beginGrouping]; - [NSAnimationContext.currentContext setDuration:0]; - - // Resize and position the CALayers - CGFloat width = imageScaledSize.width + (BORDER_SIZE * 2); - CGFloat height = imageScaledSize.height + (BORDER_SIZE * 2); - - CGFloat offsetX = (self.frame.size.width - width) / 2; - CGFloat offsetY = (self.frame.size.height - height) / 2; + CGFloat width = imageScaledSize.width; + CGFloat height = imageScaledSize.height; + + CGFloat offsetX = (frameSize.width - width) / 2; + CGFloat offsetY = (frameSize.height - height) / 2; NSRect alignedRect = [self backingAlignedRect:NSMakeRect(offsetX, offsetY, width, height) options:NSAlignAllEdgesNearest]; self.backLayer.frame = alignedRect; - self.pictureLayer.frame = NSInsetRect(alignedRect, 2, 2); - - [NSAnimationContext endGrouping]; + self.pictureLayer.frame = NSInsetRect(alignedRect, borderSize, borderSize); - // Update the properties - self.scale = self.pictureLayer.frame.size.width / imageSize.width * backingScaleFactor; - self.pictureFrame = self.pictureLayer.frame; + [CATransaction commit]; } } /** - * Given the size of the preview image to be shown, returns the best possible - * size for the view. + * Given the size of the preview image to be shown, + * returns the best possible size for the view. */ -- (NSSize)optimalViewSizeForImageSize:(NSSize)imageSize minSize:(NSSize)minSize +- (NSSize)optimalViewSizeForImageSize:(NSSize)imageSize minSize:(NSSize)minSize scaleFactor:(CGFloat)scaleFactor { - if (self.scaleFactor != 1.0) - { - // HiDPI mode usually display everything - // with double pixel count, but we don't - // want to double the size of the video - imageSize.height /= self.scaleFactor; - imageSize.width /= self.scaleFactor; - } - - NSSize screenSize = self.window.screen.visibleFrame.size; - CGFloat maxWidth = screenSize.width; - CGFloat maxHeight = screenSize.height; - - NSSize resultSize = imageSize; - - if (resultSize.width > maxWidth || resultSize.height > maxHeight) - { - resultSize = [self scaledSize:resultSize toFit:screenSize]; - } + NSSize resultSize = [self imageScaledSize:imageSize + toFit:self.window.screen.visibleFrame.size + borderSize:self.showBorder ? BORDER_SIZE : 0 + scaleFactor:scaleFactor]; // If necessary, grow to minimum dimensions to ensure controls overlay is not obstructed if (resultSize.width < minSize.width) @@ -261,20 +242,10 @@ resultSize.height = minSize.height; } - // Add the border - if (self.showBorder) - { - resultSize.width += BORDER_SIZE * 2; - resultSize.height += BORDER_SIZE * 2; - } - NSRect alignedRect = [self backingAlignedRect:NSMakeRect(0, 0, resultSize.width, resultSize.height) options:NSAlignAllEdgesNearest]; - resultSize.width = alignedRect.size.width; - resultSize.height = alignedRect.size.height; - - return resultSize; + return alignedRect.size; } #pragma mark - Accessibility |