Revision: 14211
http://sourceforge.net/p/skim-app/code/14211
Author: hofman
Date: 2024-04-14 14:40:31 +0000 (Sun, 14 Apr 2024)
Log Message:
-----------
Animate full screen window containing bitmap of displayed page to enter and
exit presentation, so we don't need to use deprecated CGWindow API. Requires
reorginization of enter/exit presentation code.
Modified Paths:
--------------
trunk/SKMainWindowController_FullScreen.m
Modified: trunk/SKMainWindowController_FullScreen.m
===================================================================
--- trunk/SKMainWindowController_FullScreen.m 2024-04-12 09:29:44 UTC (rev
14210)
+++ trunk/SKMainWindowController_FullScreen.m 2024-04-14 14:40:31 UTC (rev
14211)
@@ -227,29 +227,6 @@
if ([pdfView hasReadingBar])
[pdfView toggleReadingBar];
- if ([self presentationNotesDocument]) {
- PDFDocument *pdfDoc = [[self presentationNotesDocument] pdfDocument];
- NSInteger offset = [self presentationNotesOffset];
- NSUInteger pageIndex = MAX(0, MIN((NSInteger)[pdfDoc pageCount],
(NSInteger)[[pdfView currentPage] pageIndex] + offset));
- if ([self presentationNotesDocument] == [self document]) {
- presentationPreview = [[SKSnapshotWindowController alloc] init];
-
- [presentationPreview setDelegate:self];
-
- NSScreen *screen = [[self window] screen];
- screen = [[self alternateScreensForScreen:screen] firstObject] ?:
screen;
-
- [presentationPreview setPdfDocument:[pdfView document]
- previewPageNumber:pageIndex
- displayOnScreen:screen];
-
- [[self document] addWindowController:presentationPreview];
- } else {
- [[self presentationNotesDocument] setCurrentPage:[pdfDoc
pageAtIndex:pageIndex]];
- }
- [self addPresentationNotesNavigation];
- }
-
if ([[NSUserDefaults standardUserDefaults]
boolForKey:SKResizablePresentationKey]) {
[[self window] setStyleMask:[[self window] styleMask] |
NSWindowStyleMaskResizable];
[[self window] setHasShadow:YES];
@@ -282,26 +259,27 @@
}
}
-- (void)addPresentationWindowOnScreen:(NSScreen *)screen {
- if ([[mainWindow firstResponder] isDescendantOf:pdfSplitView])
- [mainWindow makeFirstResponder:nil];
-
- NSWindow *fullScreenWindow = [[SKFullScreenWindow alloc]
initWithScreen:screen ?: [mainWindow screen]];
-
- [mainWindow setDelegate:nil];
- [self setWindow:fullScreenWindow];
- [[fullScreenWindow contentView] setWantsLayer:YES];
- [fullScreenWindow setAlphaValue:0.0];
- [fullScreenWindow orderFront:nil];
- [fullScreenWindow makeKeyWindow];
- [NSApp updatePresentationOptionsForWindow:fullScreenWindow];
- [mainWindow setAnimationBehavior:NSWindowAnimationBehaviorNone];
- [mainWindow orderOut:nil];
- [mainWindow setAnimationBehavior:NSWindowAnimationBehaviorDefault];
- if ([[NSUserDefaults standardUserDefaults]
boolForKey:SKUseNormalLevelForPresentationKey])
- [fullScreenWindow setLevel:NSNormalWindowLevel];
- [fullScreenWindow orderFront:nil];
- [NSApp addWindowsItem:fullScreenWindow title:[self
windowTitleForDocumentDisplayName:[[self document] displayName]] filename:NO];
+- (void)showPresentationNotes {
+ PDFDocument *pdfDoc = [[self presentationNotesDocument] pdfDocument];
+ NSInteger offset = [self presentationNotesOffset];
+ NSUInteger pageIndex = MAX(0, MIN((NSInteger)[pdfDoc pageCount],
(NSInteger)[[pdfView currentPage] pageIndex] + offset));
+ if ([self presentationNotesDocument] == [self document]) {
+ presentationPreview = [[SKSnapshotWindowController alloc] init];
+
+ [presentationPreview setDelegate:self];
+
+ NSScreen *screen = [[self window] screen];
+ screen = [[self alternateScreensForScreen:screen] firstObject] ?:
screen;
+
+ [presentationPreview setPdfDocument:[pdfView document]
+ previewPageNumber:pageIndex
+ displayOnScreen:screen];
+
+ [[self document] addWindowController:presentationPreview];
+ } else {
+ [[self presentationNotesDocument] setCurrentPage:[pdfDoc
pageAtIndex:pageIndex]];
+ }
+ [self addPresentationNotesNavigation];
}
- (void)removePresentationWindow {
@@ -329,7 +307,6 @@
[NSApp updatePresentationOptionsForWindow:mainWindow];
[mainWindow setAnimationBehavior:NSWindowAnimationBehaviorDefault];
[NSApp removeWindowsItem:fullScreenWindow];
- [fullScreenWindow orderOut:nil];
}
- (void)showStaticContentForWindow:(NSWindow *)window {
@@ -367,6 +344,61 @@
[window setAlphaValue:0.0];
}
+static inline CGRect SKPixelAlignedRect(CGRect rect, CGContextRef context) {
+ CGRect r;
+ rect = CGContextConvertRectToDeviceSpace(context, rect);
+ r.origin.x = round(CGRectGetMinX(rect));
+ r.origin.y = round(CGRectGetMinY(rect));
+ r.size.width = round(CGRectGetMaxX(rect)) - CGRectGetMinX(r);
+ r.size.height = round(CGRectGetMaxY(rect)) - CGRectGetMinY(r);
+ return CGRectGetWidth(r) > 0.0 && CGRectGetHeight(r) > 0.0 ?
CGContextConvertRectToUserSpace(context, r) : NSZeroRect;
+}
+
+- (void)showStaticContentInPresentationWindow:(NSWindow *)window {
+ NSRect rect = [[window contentView] bounds];
+ NSBitmapImageRep *imageRep = nil;
+
+ if ([pdfView window] == window) {
+ imageRep = [pdfView bitmapImageRepCachingDisplay];
+ } else {
+ PDFPage *page = [pdfView currentPage];
+ NSRect pageRect = [page boundsForBox:kPDFDisplayBoxCropBox];
+ CGFloat scale = 1.0;
+ if (([page rotation] % 180) != 0)
+ pageRect = NSMakeRect(0.0, 0.0, NSHeight(pageRect),
NSWidth(pageRect));
+ if (NSHeight(pageRect) * NSWidth(rect) < NSWidth(pageRect) *
NSHeight(rect)) {
+ scale = NSWidth(rect) / NSWidth(pageRect);
+ pageRect = NSMakeRect(0.0, 0.5 * (NSHeight(rect) - scale *
NSHeight(pageRect)), NSWidth(rect), scale * NSHeight(pageRect));
+ } else {
+ scale = NSHeight(rect) / NSHeight(pageRect);
+ pageRect = NSMakeRect(0.5 * (NSWidth(rect) - scale *
NSWidth(pageRect)), 0.0, scale * NSWidth(pageRect), NSHeight(rect));
+ }
+ imageRep = [[window contentView]
bitmapImageRepForCachingDisplayInRect:rect];
+ CGContextRef context = [[NSGraphicsContext
graphicsContextWithBitmapImageRep:imageRep] CGContext];
+ CGContextSetFillColorWithColor(context,
CGColorGetConstantColor(kCGColorWhite));
+ CGContextFillRect(context,
SKPixelAlignedRect(NSRectToCGRect(pageRect), context));
+ CGContextSaveGState(context);
+ CGContextTranslateCTM(context, NSMinX(pageRect), NSMinY(pageRect));
+ CGContextScaleCTM(context, scale, scale);
+ [page drawWithBox:kPDFDisplayBoxCropBox toContext:context];
+ CGContextRestoreGState(context);
+ }
+
+ NSImage *image = [[NSImage alloc] initWithSize:rect.size];
+ [image addRepresentation:imageRep];
+
+ NSImageView *imageView = [[NSImageView alloc] initWithFrame:rect];
+ [imageView setEditable:NO];
+ [imageView setImageFrameStyle:NSImageFrameNone];
+ [imageView setImageScaling:NSImageScaleProportionallyUpOrDown];
+ [imageView setImage:image];
+ [imageView setContentFilters:SKColorEffectFilters()];
+ [imageView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ if ([pdfView window] == window)
+ [pdfView removeFromSuperview];
+ [[window contentView] addSubview:imageView];
+}
+
#pragma mark API
- (void)enterFullscreen {
@@ -395,24 +427,12 @@
return;
}
- PDFPage *page = [[self pdfView] currentPage];
-
mwcFlags.isSwitchingFullScreen = 1;
- interactionMode = SKPresentationMode;
-
- [self showStaticContentForWindow:[self window]];
-
// remember normal setup to return to, we must do this before changing the
interactionMode
[savedNormalSetup setDictionary:[self currentPDFSettings]];
- if ([[[self window] tabbedWindows] count] > 1) {
- NSUInteger tabIndex = [[[self window] tabbedWindows]
indexOfObject:[self window]];
- [savedNormalSetup setObject:[[self window] tabGroup]
forKey:TABGROUP_KEY];
- [savedNormalSetup setObject:[NSNumber
numberWithUnsignedInteger:tabIndex] forKey:TABINDEX_KEY];
- [[self window] moveTabToNewWindow:nil];
- [animationWindow orderWindow:NSWindowAbove relativeTo:[self window]];
- }
+ interactionMode = SKPresentationMode;
NSScreen *screen = [mainWindow screen];
if ([self presentationNotesDocument] && [self presentationNotesDocument]
!= [self document]) {
@@ -421,42 +441,70 @@
screen = [screens firstObject];
}
- [self addPresentationWindowOnScreen:screen];
+ NSWindow *fullScreenWindow = [[SKFullScreenWindow alloc]
initWithScreen:screen ?: [mainWindow screen]];
+ [[fullScreenWindow contentView] setWantsLayer:YES];
+ [fullScreenWindow setAlphaValue:0.0];
+ [self showStaticContentInPresentationWindow:fullScreenWindow];
+ [fullScreenWindow orderFront:nil];
- if ([self hasOverview])
- [self hideOverviewAnimating:NO];
+ if ([self presentationNotesDocument])
+ [self showPresentationNotes];
- [self enterPresentationMode];
+ BOOL shouldFadeOut = NSContainsRect([fullScreenWindow frame], [[self
window] frame]) == NO && [[[self window] tabbedWindows] count] <= 1;
- NSWindow *fullScreenWindow = [self window];
-
- [[fullScreenWindow contentView] addSubviewWithConstraints:pdfView];
- [pdfView layoutDocumentView];
- [pdfView requiresDisplay];
- [fullScreenWindow makeFirstResponder:pdfView];
- [fullScreenWindow recalculateKeyViewLoop];
- [fullScreenWindow setDelegate:self];
-
- if ([[pdfView currentPage] isEqual:page] == NO)
- [pdfView goToPage:page];
-
- mwcFlags.isSwitchingFullScreen = 0;
-
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:PRESENTATION_DURATION];
[context setTimingFunction:[CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[fullScreenWindow animator] setAlphaValue:1.0];
- if (NSContainsRect([fullScreenWindow frame], [animationWindow
frame]) == NO)
- [[animationWindow animator] setAlphaValue:0.0];
+ if (shouldFadeOut)
+ [[mainWindow animator] setAlphaValue:0.0];
[[[presentationPreview window] animator] setAlphaValue:1.0];
}
completionHandler:^{
- [animationWindow orderOut:nil];
- animationWindow = nil;
+ PDFPage *page = [[self pdfView] currentPage];
+
+ if ([[[self window] tabbedWindows] count] > 1) {
+ NSUInteger tabIndex = [[[self window] tabbedWindows]
indexOfObject:[self window]];
+ [savedNormalSetup setObject:[[self window] tabGroup]
forKey:TABGROUP_KEY];
+ [savedNormalSetup setObject:[NSNumber
numberWithUnsignedInteger:tabIndex] forKey:TABINDEX_KEY];
+ [[self window] moveTabToNewWindow:nil];
+ [animationWindow orderWindow:NSWindowAbove relativeTo:[self
window]];
+ }
+
+ [mainWindow setDelegate:nil];
+ [self setWindow:fullScreenWindow];
+ [NSApp updatePresentationOptionsForWindow:fullScreenWindow];
+ [mainWindow setAnimationBehavior:NSWindowAnimationBehaviorNone];
+ [mainWindow orderOut:nil];
+ [mainWindow setAnimationBehavior:NSWindowAnimationBehaviorDefault];
+ [mainWindow setAlphaValue:1.0];
+ if ([[NSUserDefaults standardUserDefaults]
boolForKey:SKUseNormalLevelForPresentationKey])
+ [fullScreenWindow setLevel:NSNormalWindowLevel];
+ [fullScreenWindow makeKeyAndOrderFront:nil];
+ [NSApp addWindowsItem:fullScreenWindow title:[self
windowTitleForDocumentDisplayName:[[self document] displayName]] filename:NO];
+
+ if ([self hasOverview])
+ [self hideOverviewAnimating:NO];
+
+ [self enterPresentationMode];
+
+ [[[[fullScreenWindow contentView] subviews] firstObject]
removeFromSuperview];
+ [[fullScreenWindow contentView] addSubviewWithConstraints:pdfView];
+ [pdfView layoutDocumentView];
+ [pdfView requiresDisplay];
+ [fullScreenWindow makeFirstResponder:pdfView];
+ [fullScreenWindow recalculateKeyViewLoop];
+ [fullScreenWindow setDelegate:self];
+
+ if ([[pdfView currentPage] isEqual:page] == NO)
+ [pdfView goToPage:page];
+
+ [pdfView setPresentationMode:YES];
+
+ [touchBarController interactionModeChanged];
+
+ mwcFlags.isSwitchingFullScreen = 0;
}];
-
- [pdfView setPresentationMode:YES];
- [touchBarController interactionModeChanged];
}
- (void)exitPresentation {
@@ -484,7 +532,7 @@
NSWindow *fullScreenWindow = [self window];
- [self showStaticContentForWindow:fullScreenWindow];
+ [self showStaticContentInPresentationWindow:fullScreenWindow];
while ([[fullScreenWindow childWindows] count] > 0) {
NSWindow *childWindow = [[fullScreenWindow childWindows] lastObject];
@@ -530,9 +578,9 @@
[self removePresentationWindow];
- [animationWindow setLevel:NSPopUpMenuWindowLevel];
+ [fullScreenWindow setLevel:NSPopUpMenuWindowLevel];
- BOOL covered = NSContainsRect([animationWindow frame], [mainWindow frame]);
+ BOOL covered = NSContainsRect([fullScreenWindow frame], [mainWindow
frame]);
if (covered)
[mainWindow setAlphaValue:1.0];
@@ -547,12 +595,11 @@
[context setTimingFunction:[CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
if (covered == NO)
[[mainWindow animator] setAlphaValue:1.0];
- [[animationWindow animator] setAlphaValue:0.0];
+ [[fullScreenWindow animator] setAlphaValue:0.0];
[[[presentationPreview window] animator] setAlphaValue:0.0];
}
completionHandler:^{
- [animationWindow orderOut:nil];
- animationWindow = nil;
+ [fullScreenWindow orderOut:nil];
if (presentationPreview) {
[[presentationPreview window]
setAnimationBehavior:NSWindowAnimationBehaviorNone];
[presentationPreview close];
@@ -572,7 +619,7 @@
}
- (BOOL)canEnterPresentation {
- return mwcFlags.isSwitchingFullScreen == 0 && [[self pdfDocument]
isLocked] == NO && [self interactionMode] != SKPresentationMode;
+ return mwcFlags.isSwitchingFullScreen == 0 && [[self pdfDocument]
isLocked] == NO && [self interactionMode] != SKPresentationMode && ([[[self
window] tabbedWindows] count] <= 1 || [[[self window] tabGroup] selectedWindow]
== [self window]);
}
- (BOOL)canExitFullscreen {
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit