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

Reply via email to