summaryrefslogtreecommitdiffstats
path: root/macosx/HBPreviewView.m
diff options
context:
space:
mode:
authorDamiano Galassi <[email protected]>2019-10-05 19:00:30 +0200
committerDamiano Galassi <[email protected]>2019-10-05 19:00:30 +0200
commit4238775818207edef7f303dabf99684f5542bc53 (patch)
tree0fc0b4a659abd329f394a92c31adcfcf6085cefe /macosx/HBPreviewView.m
parentb8fc24a311d3f0163fd39d758d54096f37dbb8b3 (diff)
Improve preview window sizing.
Diffstat (limited to 'macosx/HBPreviewView.m')
-rw-r--r--macosx/HBPreviewView.m163
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