summaryrefslogtreecommitdiffstats
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
parentb8fc24a311d3f0163fd39d758d54096f37dbb8b3 (diff)
Improve preview window sizing.
-rw-r--r--macosx/Base.lproj/PicturePreview.xib12
-rw-r--r--macosx/HBPreviewController.m114
-rw-r--r--macosx/HBPreviewView.h2
-rw-r--r--macosx/HBPreviewView.m163
-rw-r--r--macosx/NSWindow+HBAdditions.h2
-rw-r--r--macosx/NSWindow+HBAdditions.m46
6 files changed, 168 insertions, 171 deletions
diff --git a/macosx/Base.lproj/PicturePreview.xib b/macosx/Base.lproj/PicturePreview.xib
index 5a5562ffd..183f39eb0 100644
--- a/macosx/Base.lproj/PicturePreview.xib
+++ b/macosx/Base.lproj/PicturePreview.xib
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14113" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
- <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14113"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15504"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -14,16 +14,16 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
- <window title="Preview" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="5" userLabel="PreviewPanel">
- <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
+ <window title="Preview" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="5" userLabel="PreviewPanel">
+ <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<rect key="contentRect" x="221" y="837" width="500" height="360"/>
- <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
+ <rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/>
<value key="minSize" type="size" width="480" height="360"/>
<view key="contentView" id="6">
<rect key="frame" x="0.0" y="0.0" width="500" height="360"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
- <customView id="ooo-9X-9Al" customClass="HBPreviewView">
+ <customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ooo-9X-9Al" customClass="HBPreviewView">
<rect key="frame" x="0.0" y="0.0" width="500" height="360"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</customView>
diff --git a/macosx/HBPreviewController.m b/macosx/HBPreviewController.m
index e3d9c72af..4d8e5ed11 100644
--- a/macosx/HBPreviewController.m
+++ b/macosx/HBPreviewController.m
@@ -63,12 +63,12 @@
// We need the center and we can't use the
// standard NSWindow autosave because we change
// the window size at startup.
- NSString *centerString = [[NSUserDefaults standardUserDefaults] objectForKey:@"HBPreviewWindowCenter"];
+ NSString *centerString = [NSUserDefaults.standardUserDefaults stringForKey:@"HBPreviewWindowCenter"];
if (centerString.length)
{
NSPoint center = NSPointFromString(centerString);
self.windowCenterPoint = center;
- [self.window HB_resizeToBestSizeForViewSize:NSMakeSize(MIN_WIDTH, MIN_HEIGHT) center:self.windowCenterPoint animate:NO];
+ [self.window HB_resizeToBestSizeForViewSize:NSMakeSize(MIN_WIDTH, MIN_HEIGHT) keepInScreenRect:YES centerPoint:center animate:NO];
}
else
{
@@ -167,7 +167,13 @@
self.window.title = NSLocalizedString(@"Preview", @"Preview -> window title");
self.pictureHUD.generator = nil;
}
+
[self switchStateToHUD:self.pictureHUD];
+
+ if (generator)
+ {
+ [self resizeToOptimalSize];
+ }
}
- (void)reloadPreviews
@@ -176,6 +182,7 @@
{
[self.generator cancel];
[self switchStateToHUD:self.pictureHUD];
+ [self resizeToOptimalSize];
}
}
@@ -204,20 +211,43 @@
[self.generator purgeImageCache];
}
+#pragma mark - Window sizing
+
+- (void)resizeToOptimalSize
+{
+ if (!(self.window.styleMask & NSWindowStyleMaskFullScreen))
+ {
+ if (self.previewView.fitToView)
+ {
+ [self.window setFrame:self.window.screen.visibleFrame display:YES animate:YES];
+ }
+ else
+ {
+ // Get the optimal view size for the image
+ NSSize windowSize = [self.previewView optimalViewSizeForImageSize:self.generator.imageSize
+ minSize:NSMakeSize(MIN_WIDTH, MIN_HEIGHT)
+ scaleFactor:self.window.backingScaleFactor];
+ // Scale the window to the image size
+ [self.window HB_resizeToBestSizeForViewSize:windowSize keepInScreenRect:YES centerPoint:NSZeroPoint animate:self.window.isVisible];
+ }
+ }
+
+ [self updateSizeLabels];
+}
+
- (void)windowDidChangeBackingProperties:(NSNotification *)notification
{
NSWindow *theWindow = (NSWindow *)notification.object;
CGFloat newBackingScaleFactor = theWindow.backingScaleFactor;
- CGFloat oldBackingScaleFactor = [notification.userInfo[@"NSBackingPropertyOldScaleFactorKey"] doubleValue];
+ CGFloat oldBackingScaleFactor = [notification.userInfo[NSBackingPropertyOldScaleFactorKey] doubleValue];
if (newBackingScaleFactor != oldBackingScaleFactor)
{
- // Scale factor changed, update the preview window
- // to the new situation
+ // Scale factor changed, resize the preview window
if (self.generator)
{
- [self reloadPreviews];
+ [self resizeToOptimalSize];
}
}
}
@@ -229,13 +259,20 @@
if (self.previewView.fitToView == NO)
{
self.windowCenterPoint = [self.window HB_centerPoint];
- [[NSUserDefaults standardUserDefaults] setObject:NSStringFromPoint(self.windowCenterPoint) forKey:@"HBPreviewWindowCenter"];
+ [NSUserDefaults.standardUserDefaults setObject:NSStringFromPoint(self.windowCenterPoint) forKey:@"HBPreviewWindowCenter"];
}
}
- (void)windowDidResize:(NSNotification *)notification
{
[self updateSizeLabels];
+ if (self.currentHUD == self.playerHUD)
+ {
+ [CATransaction begin];
+ CATransaction.disableActions = YES;
+ self.player.layer.frame = self.previewView.pictureFrame;
+ [CATransaction commit];
+ }
}
- (void)updateSizeLabels
@@ -247,7 +284,7 @@
NSMutableString *scaleString = [NSMutableString string];
if (scale * 100.0 != 100)
{
- [scaleString appendFormat:NSLocalizedString(@"(%.0f%% actual size)", @"Preview -> size info label"), scale * 100.0];
+ [scaleString appendFormat:NSLocalizedString(@"(%.0f%% actual size)", @"Preview -> size info label"), floor(scale * 100.0)];
}
else
{
@@ -269,6 +306,12 @@
}
}
+- (void)toggleScaleToScreen
+{
+ self.previewView.fitToView = !self.previewView.fitToView;
+ [self resizeToOptimalSize];
+}
+
#pragma mark - Hud State
/**
@@ -299,14 +342,16 @@
// Show the current hud
NSMutableArray<NSViewController<HBHUD> *> *huds = [@[self.pictureHUD, self.encodingHUD, self.playerHUD] mutableCopy];
[huds removeObject:hud];
- for (NSViewController *controller in huds) {
+ for (NSViewController *controller in huds)
+ {
controller.view.hidden = YES;
}
+
if (self.generator)
{
hud.view.hidden = NO;
hud.view.layer.opacity = 1.0;
- };
+ }
[self.window makeFirstResponder:hud.view];
[self startHudTimer];
@@ -431,51 +476,13 @@
[self displayPreviewAtIndex:self.pictureHUD.selectedIndex];
}
-/**
- * Adjusts the window to draw the current picture (fPicture) adjusting its size as
- * necessary to display as much of the picture as possible.
- */
- (void)displayPreviewAtIndex:(NSUInteger)idx
{
- if (!self.generator)
- {
- return;
- }
-
- if (self.window.isVisible)
+ if (self.generator && self.window.isVisible)
{
- CGImageRef fPreviewImage = [self.generator copyImageAtIndex:idx shouldCache:YES];
- [self.previewView setImage:fPreviewImage];
- CFRelease(fPreviewImage);
- }
-
- if (self.previewView.fitToView == NO && !(self.window.styleMask & NSWindowStyleMaskFullScreen))
- {
- // Get the optimal view size for the image
- NSSize imageScaledSize = [self.generator imageSize];
-
- // Scale the window to the image size
- NSSize windowSize = [self.previewView optimalViewSizeForImageSize:imageScaledSize minSize:NSMakeSize(MIN_WIDTH, MIN_HEIGHT)];
- [self.window HB_resizeToBestSizeForViewSize:windowSize center:self.windowCenterPoint animate:self.window.isVisible];
- }
-
- [self updateSizeLabels];
-}
-
-- (void)toggleScaleToScreen
-{
- if (self.previewView.fitToView == YES)
- {
- self.previewView.fitToView = NO;
- [self displayPreviewAtIndex:self.pictureHUD.selectedIndex];
- }
- else
- {
- self.previewView.fitToView = YES;
- if (!(self.window.styleMask & NSWindowStyleMaskFullScreen))
- {
- [self.window setFrame:self.window.screen.visibleFrame display:YES animate:YES];
- }
+ CGImageRef image = [self.generator copyImageAtIndex:idx shouldCache:YES];
+ self.previewView.image = image;
+ CFRelease(image);
}
}
@@ -593,8 +600,7 @@
CALayer *playerLayer = self.player.layer;
playerLayer.frame = self.previewView.pictureFrame;
- [self.window.contentView.layer insertSublayer:playerLayer atIndex:1];
-
+ [self.previewView.layer insertSublayer:playerLayer atIndex:10];
self.playerHUD.player = self.player;
}
diff --git a/macosx/HBPreviewView.h b/macosx/HBPreviewView.h
index e521aa9f9..29d0ae867 100644
--- a/macosx/HBPreviewView.h
+++ b/macosx/HBPreviewView.h
@@ -49,7 +49,7 @@ NS_ASSUME_NONNULL_BEGIN
* 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;
@end
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
diff --git a/macosx/NSWindow+HBAdditions.h b/macosx/NSWindow+HBAdditions.h
index 4f4116013..7adb69d5d 100644
--- a/macosx/NSWindow+HBAdditions.h
+++ b/macosx/NSWindow+HBAdditions.h
@@ -11,7 +11,7 @@
/**
* Resizes the entire window to accommodate a view of a particular size.
*/
-- (void)HB_resizeToBestSizeForViewSize:(NSSize)viewSize center:(NSPoint)center animate:(BOOL)performAnimation;
+- (void)HB_resizeToBestSizeForViewSize:(NSSize)viewSize keepInScreenRect:(BOOL)keepInScreenRect centerPoint:(NSPoint)center animate:(BOOL)animateFlag;
/**
* Calculates and returns the center point of the window
diff --git a/macosx/NSWindow+HBAdditions.m b/macosx/NSWindow+HBAdditions.m
index daf572bfa..d783ee8bc 100644
--- a/macosx/NSWindow+HBAdditions.m
+++ b/macosx/NSWindow+HBAdditions.m
@@ -8,7 +8,7 @@
@implementation NSWindow (HBAdditions)
-- (void)HB_resizeToBestSizeForViewSize:(NSSize)viewSize center:(NSPoint)center animate:(BOOL)animateFlag
+- (void)HB_resizeToBestSizeForViewSize:(NSSize)viewSize keepInScreenRect:(BOOL)keepInScreenRect centerPoint:(NSPoint)center animate:(BOOL)animateFlag
{
NSSize currentSize = self.contentView.frame.size;
NSRect frame = self.frame;
@@ -45,22 +45,42 @@
// sure that upon resize we do not have the window off the screen
// So check the origin against the screen origin and adjust if
// necessary.
- NSSize screenSize = self.screen.visibleFrame.size;
- NSPoint screenOrigin = self.screen.visibleFrame.origin;
-
+
+ if (center.x == 0 && center.y == 0)
+ {
+ center = [self HB_centerPoint];
+ }
frame.origin.x = center.x - floor(frame.size.width / 2);
frame.origin.y = center.y - floor(frame.size.height / 2);
- // our origin is off the screen to the left
- if (frame.origin.x < screenOrigin.x)
+ if (keepInScreenRect)
{
- // so shift our origin to the right
- frame.origin.x = screenOrigin.x;
- }
- else if ((frame.origin.x + frame.size.width) > (screenOrigin.x + screenSize.width))
- {
- // the right side of the preview is off the screen, so shift to the left
- frame.origin.x = (screenOrigin.x + screenSize.width) - frame.size.width;
+ NSSize screenSize = self.screen.visibleFrame.size;
+ NSPoint screenOrigin = self.screen.visibleFrame.origin;
+
+ // our origin is off the screen to the left
+ if (frame.origin.x < screenOrigin.x)
+ {
+ // so shift our origin to the right
+ frame.origin.x = screenOrigin.x;
+ }
+ else if ((frame.origin.x + frame.size.width) > (screenOrigin.x + screenSize.width))
+ {
+ // the right side of the preview is off the screen, so shift to the left
+ frame.origin.x = (screenOrigin.x + screenSize.width) - frame.size.width;
+ }
+
+ // our origin is off the screen to the bottom
+ if (frame.origin.y < screenOrigin.y)
+ {
+ // so shift our origin to the top
+ frame.origin.y = screenOrigin.y;
+ }
+ else if ((frame.origin.y + frame.size.height) > (screenOrigin.y + screenSize.height))
+ {
+ // the top side of the preview is off the screen, so shift to the bottom
+ frame.origin.y = (screenOrigin.y + screenSize.height) - frame.size.height;
+ }
}
[self setFrame:frame display:YES animate:animateFlag];