Revision: 2939
          http://skim-app.svn.sourceforge.net/skim-app/?rev=2939&view=rev
Author:   hofman
Date:     2007-09-19 11:46:18 -0700 (Wed, 19 Sep 2007)

Log Message:
-----------
Optionally add a splitview to show a part of the PDF in a pane below the main 
PDF. Similar to snapshots but moved into the main window. Can be useful to keep 
e.g. the bibliography. Use a zoomable PDF view with another popup for the page.

Modified Paths:
--------------
    trunk/Dutch.lproj/MainMenu.nib/classes.nib
    trunk/Dutch.lproj/MainMenu.nib/info.nib
    trunk/Dutch.lproj/MainMenu.nib/keyedobjects.nib
    trunk/English.lproj/MainMenu.nib/classes.nib
    trunk/English.lproj/MainMenu.nib/keyedobjects.nib
    trunk/French.lproj/MainMenu.nib/classes.nib
    trunk/French.lproj/MainMenu.nib/info.nib
    trunk/French.lproj/MainMenu.nib/keyedobjects.nib
    trunk/Italian.lproj/MainMenu.nib/classes.nib
    trunk/Italian.lproj/MainMenu.nib/keyedobjects.nib
    trunk/SKMainWindowController.h
    trunk/SKMainWindowController.m
    trunk/SKSplitView.h
    trunk/SKSplitView.m
    trunk/Skim.xcodeproj/project.pbxproj

Added Paths:
-----------
    trunk/SKSecondaryPDFView.h
    trunk/SKSecondaryPDFView.m

Modified: trunk/Dutch.lproj/MainMenu.nib/classes.nib
===================================================================
--- trunk/Dutch.lproj/MainMenu.nib/classes.nib  2007-09-19 16:40:23 UTC (rev 
2938)
+++ trunk/Dutch.lproj/MainMenu.nib/classes.nib  2007-09-19 18:46:18 UTC (rev 
2939)
@@ -60,6 +60,7 @@
                 togglePresentation = id; 
                 toggleReadingBar = id; 
                 toggleRightSidePane = id; 
+                toggleSplitPDF = id; 
                 toggleStatusBar = id; 
             }; 
             CLASS = FirstResponder; 

Modified: trunk/Dutch.lproj/MainMenu.nib/info.nib
===================================================================
--- trunk/Dutch.lproj/MainMenu.nib/info.nib     2007-09-19 16:40:23 UTC (rev 
2938)
+++ trunk/Dutch.lproj/MainMenu.nib/info.nib     2007-09-19 18:46:18 UTC (rev 
2939)
@@ -7,10 +7,14 @@
        <key>IBEditorPositions</key>
        <dict>
                <key>29</key>
-               <string>140 614 542 44 0 0 1440 938 </string>
+               <string>140 614 635 44 0 0 1440 938 </string>
        </dict>
        <key>IBFramework Version</key>
        <string>446.1</string>
+       <key>IBOpenObjects</key>
+       <array>
+               <integer>29</integer>
+       </array>
        <key>IBSystem Version</key>
        <string>8R218</string>
 </dict>

Modified: trunk/Dutch.lproj/MainMenu.nib/keyedobjects.nib
===================================================================
(Binary files differ)

Modified: trunk/English.lproj/MainMenu.nib/classes.nib
===================================================================
--- trunk/English.lproj/MainMenu.nib/classes.nib        2007-09-19 16:40:23 UTC 
(rev 2938)
+++ trunk/English.lproj/MainMenu.nib/classes.nib        2007-09-19 18:46:18 UTC 
(rev 2939)
@@ -60,6 +60,7 @@
                 togglePresentation = id; 
                 toggleReadingBar = id; 
                 toggleRightSidePane = id; 
+                toggleSplitPDF = id; 
                 toggleStatusBar = id; 
             }; 
             CLASS = FirstResponder; 

Modified: trunk/English.lproj/MainMenu.nib/keyedobjects.nib
===================================================================
(Binary files differ)

Modified: trunk/French.lproj/MainMenu.nib/classes.nib
===================================================================
--- trunk/French.lproj/MainMenu.nib/classes.nib 2007-09-19 16:40:23 UTC (rev 
2938)
+++ trunk/French.lproj/MainMenu.nib/classes.nib 2007-09-19 18:46:18 UTC (rev 
2939)
@@ -60,6 +60,7 @@
                 togglePresentation = id; 
                 toggleReadingBar = id; 
                 toggleRightSidePane = id; 
+                toggleSplitPDF = id; 
                 toggleStatusBar = id; 
             }; 
             CLASS = FirstResponder; 

Modified: trunk/French.lproj/MainMenu.nib/info.nib
===================================================================
--- trunk/French.lproj/MainMenu.nib/info.nib    2007-09-19 16:40:23 UTC (rev 
2938)
+++ trunk/French.lproj/MainMenu.nib/info.nib    2007-09-19 18:46:18 UTC (rev 
2939)
@@ -7,11 +7,15 @@
        <key>IBEditorPositions</key>
        <dict>
                <key>29</key>
-               <string>140 614 542 44 0 0 1440 938 </string>
+               <string>140 614 603 44 0 0 1440 938 </string>
        </dict>
        <key>IBFramework Version</key>
        <string>446.1</string>
+       <key>IBOpenObjects</key>
+       <array>
+               <integer>29</integer>
+       </array>
        <key>IBSystem Version</key>
-       <string>8R2218</string>
+       <string>8R218</string>
 </dict>
 </plist>

Modified: trunk/French.lproj/MainMenu.nib/keyedobjects.nib
===================================================================
(Binary files differ)

Modified: trunk/Italian.lproj/MainMenu.nib/classes.nib
===================================================================
--- trunk/Italian.lproj/MainMenu.nib/classes.nib        2007-09-19 16:40:23 UTC 
(rev 2938)
+++ trunk/Italian.lproj/MainMenu.nib/classes.nib        2007-09-19 18:46:18 UTC 
(rev 2939)
@@ -58,6 +58,7 @@
                 togglePresentation = id; 
                 toggleReadingBar = id; 
                 toggleRightSidePane = id; 
+                toggleSplitPDF = id; 
                 toggleStatusBar = id; 
             }; 
             CLASS = FirstResponder; 

Modified: trunk/Italian.lproj/MainMenu.nib/keyedobjects.nib
===================================================================
(Binary files differ)

Modified: trunk/SKMainWindowController.h
===================================================================
--- trunk/SKMainWindowController.h      2007-09-19 16:40:23 UTC (rev 2938)
+++ trunk/SKMainWindowController.h      2007-09-19 18:46:18 UTC (rev 2939)
@@ -64,7 +64,7 @@
 } SKPDFViewState;
 
 @class PDFOutline, SKThumbnail;
[EMAIL PROTECTED] SKPDFView, SKTocOutlineView, SKNoteOutlineView, 
SKThumbnailTableView, SKSnapshotTableView, SKSplitView, BDSKCollapsibleView, 
BDSKEdgeView, BDSKGradientView, BDSKImagePopUpButton, SKColorSwatch, 
SKStatusBar;
[EMAIL PROTECTED] SKPDFView, SKSecondaryPDFView, SKTocOutlineView, 
SKNoteOutlineView, SKThumbnailTableView, SKSnapshotTableView, SKSplitView, 
BDSKCollapsibleView, BDSKEdgeView, BDSKGradientView, BDSKImagePopUpButton, 
SKColorSwatch, SKStatusBar;
 @class SKFullScreenWindow, SKNavigationWindow, SKSideWindow, 
SKSnapshotWindowController, SKProgressController;
 
 @interface SKMainWindowController : NSWindowController {
@@ -73,6 +73,10 @@
     IBOutlet SKPDFView          *pdfView;
     IBOutlet BDSKEdgeView       *pdfContentBox;
     
+    SKSplitView                 *pdfSplitView;
+    SKSecondaryPDFView          *secondaryPdfView;
+    BDSKEdgeView                *secondaryPdfContentBox;
+    
     IBOutlet NSBox              *leftSideContentBox;
     IBOutlet NSView             *leftSideContentView;
     IBOutlet BDSKEdgeView       *leftSideEdgeView;
@@ -193,6 +197,7 @@
     
     float                       lastLeftSidePaneWidth;
     float                       lastRightSidePaneWidth;
+    float                       lastSecondaryPdfViewPaneHeight;
     
     float                       thumbnailCacheSize;
     float                       snapshotCacheSize;

Modified: trunk/SKMainWindowController.m
===================================================================
--- trunk/SKMainWindowController.m      2007-09-19 16:40:23 UTC (rev 2938)
+++ trunk/SKMainWindowController.m      2007-09-19 18:46:18 UTC (rev 2939)
@@ -80,6 +80,7 @@
 #import "SKTypeSelectHelper.h"
 #import "NSGeometry_SKExtensions.h"
 #import "SKProgressController.h"
+#import "SKSecondaryPDFView.h"
 
 #define SEGMENTED_CONTROL_HEIGHT    25.0
 #define WINDOW_X_DELTA              0.0
@@ -1885,6 +1886,59 @@
     [self setRightSidePaneState:[sender tag]];
 }
 
+- (IBAction)toggleSplitPDF:(id)sender {
+    if (pdfSplitView) {
+        
+        [pdfContentBox setFrame:[pdfSplitView frame]];
+        [splitView replaceSubview:pdfSplitView with:pdfContentBox];
+        pdfSplitView = nil;
+        secondaryPdfContentBox = nil;
+        secondaryPdfView = nil;
+        
+    } else {
+        
+        NSPoint point = [pdfView convertPoint:[pdfView bounds].origin 
toPage:[pdfView currentPage]];
+        NSRect ignored, frame1, frame2;
+        
+        pdfSplitView = [[SKSplitView alloc] initWithFrame:[pdfContentBox 
bounds]];
+        [pdfSplitView setBlendEnds:YES];
+        [pdfContentBox retain];
+        [splitView replaceSubview:pdfContentBox with:pdfSplitView];
+        [pdfSplitView release];
+        
+        frame1 = [pdfSplitView bounds];
+        NSDivideRect(frame1, &frame1, &frame2, roundf(0.7 * NSHeight(frame1)), 
NSMaxYEdge);
+        NSDivideRect(frame2, &ignored, &frame2, [pdfSplitView 
dividerThickness], NSMaxYEdge);
+        
+        [pdfContentBox setFrame:frame1];
+        [pdfSplitView addSubview:pdfContentBox];
+        [pdfContentBox release];
+        
+        secondaryPdfContentBox = [[BDSKEdgeView alloc] initWithFrame:frame1];
+        [secondaryPdfContentBox setEdges:BDSKMinXEdgeMask | BDSKMaxXEdgeMask | 
BDSKMinYEdgeMask | BDSKMaxYEdgeMask];
+        [secondaryPdfContentBox setFrame:frame2];
+        [pdfSplitView addSubview:secondaryPdfContentBox];
+        [secondaryPdfContentBox release];
+        
+        secondaryPdfView = [[SKSecondaryPDFView alloc] 
initWithFrame:[[secondaryPdfContentBox contentView] bounds]];
+        [secondaryPdfView setAutoresizingMask:NSViewWidthSizable | 
NSViewHeightSizable];
+        [secondaryPdfContentBox addSubview:secondaryPdfView];
+        [secondaryPdfView release];
+        
+        [pdfSplitView setDelegate:self];
+        [pdfSplitView adjustSubviews];
+        
+        [secondaryPdfView setDocument:[pdfView document]];
+        [secondaryPdfView setAutoScales:YES];
+        [secondaryPdfView setDisplayMode:kPDFDisplaySinglePageContinuous];
+        [secondaryPdfView setDisplaysPageBreaks:NO];
+        [secondaryPdfView setDisplayBox:kPDFDisplayBoxCropBox];
+        [secondaryPdfView goToPage:[pdfView currentPage]];
+        point = [secondaryPdfView convertPoint:[secondaryPdfView 
convertPoint:point fromPage:[secondaryPdfView currentPage]] 
toView:[secondaryPdfView documentView]];
+        [[secondaryPdfView documentView] scrollPoint:point];
+    }
+}
+
 - (IBAction)toggleFullScreen:(id)sender {
     if ([self isFullScreen])
         [self exitFullScreen:sender];
@@ -2780,6 +2834,7 @@
             if ([wc isPageVisible:page])
                 [self snapshotNeedsUpdate:wc];
         }
+        [secondaryPdfView setNeedsDisplayForAnnotation:annotation onPage:page];
     }
     [noteOutlineView reloadData];
 }
@@ -2812,6 +2867,7 @@
             if ([wc isPageVisible:page])
                 [self snapshotNeedsUpdate:wc];
         }
+        [secondaryPdfView setNeedsDisplayForAnnotation:annotation onPage:page];
     }
     [noteOutlineView reloadData];
 }
@@ -2831,6 +2887,7 @@
             if ([wc isPageVisible:oldPage] || [wc isPageVisible:newPage])
                 [self snapshotNeedsUpdate:wc];
         }
+        [secondaryPdfView setNeedsDisplay:YES];
     }
     
     [noteArrayController rearrangeObjects];
@@ -2865,6 +2922,8 @@
                 [self snapshotNeedsUpdate:wc];
         }
         
+        [secondaryPdfView setNeedsDisplayForAnnotation:annotation 
onPage:[annotation page]];
+        
         [noteArrayController rearrangeObjects];
         [noteOutlineView reloadData];
     }
@@ -2913,6 +2972,8 @@
         if (displayChanged)
             [self allThumbnailsNeedUpdate];
     }
+    
+    [secondaryPdfView setNeedsDisplay:YES];
 }
 
 - (void)handleDocumentBeginWrite:(NSNotification *)notification {
@@ -4709,6 +4770,12 @@
     } else if (action == @selector(changeRightSidePaneState:)) {
         [menuItem setState:(int)rightSidePaneState == [menuItem tag] ? 
NSOnState : NSOffState];
         return [self isPresentation] == NO;
+    } else if (action == @selector(toggleSplitPDF:)) {
+        if (secondaryPdfView)
+            [menuItem setTitle:NSLocalizedString(@"Hide Split PDF", @"Menu 
item title")];
+        else
+            [menuItem setTitle:NSLocalizedString(@"Show Split PDF", @"Menu 
item title")];
+        return [self isPresentation] == NO && [self isFullScreen] == NO;
     } else if (action == @selector(toggleStatusBar:)) {
         if ([statusBar isVisible])
             [menuItem setTitle:NSLocalizedString(@"Hide Status Bar", @"Menu 
item title")];
@@ -4754,46 +4821,95 @@
 #pragma mark SKSplitView delegate protocol
 
 - (void)splitView:(SKSplitView *)sender doubleClickedDividerAt:(int)offset{
-    if (offset == 0)
-        [self toggleLeftSidePane:self];
-    else
-        [self toggleRightSidePane:self];
+    if ([sender isEqual:splitView]) {
+        if (offset == 0)
+            [self toggleLeftSidePane:self];
+        else
+            [self toggleRightSidePane:self];
+    } else if ([sender isEqual:pdfSplitView]) {
+        NSRect primaryFrame = [pdfContentBox frame];
+        NSRect secondaryFrame = [secondaryPdfContentBox frame];
+        
+        if (NSHeight(secondaryFrame) > 0.0) {
+            lastSecondaryPdfViewPaneHeight = NSHeight(secondaryFrame); // 
cache this
+            primaryFrame.size.height += lastLeftSidePaneWidth;
+            secondaryFrame.size.height = 0.0;
+        } else {
+            if(lastSecondaryPdfViewPaneHeight <= 0.0)
+                lastSecondaryPdfViewPaneHeight = 200.0; // a reasonable value 
to start
+            if (lastSecondaryPdfViewPaneHeight > 0.5 * NSHeight(primaryFrame))
+                lastSecondaryPdfViewPaneHeight = floorf(0.5 * 
NSHeight(primaryFrame));
+            primaryFrame.size.height -= lastSecondaryPdfViewPaneHeight;
+            secondaryFrame.size.height = lastSecondaryPdfViewPaneHeight;
+        }
+        primaryFrame.origin.y = NSMaxY(secondaryFrame) + [pdfSplitView 
dividerThickness];
+        [pdfContentBox setFrame:primaryFrame];
+        [secondaryPdfContentBox setFrame:secondaryFrame];
+        [pdfSplitView setNeedsDisplay:YES];
+        [pdfSplitView adjustSubviews];
+    }
 }
 
 - (void)splitView:(NSSplitView *)sender 
resizeSubviewsWithOldSize:(NSSize)oldSize {
-    NSView *leftSideView = [[sender subviews] objectAtIndex:0];
-    NSView *mainView = [[sender subviews] objectAtIndex:1]; // pdfView
-    NSView *rightSideView = [[sender subviews] objectAtIndex:2];
-    NSRect leftSideFrame = [leftSideView frame];
-    NSRect mainFrame = [mainView frame];
-    NSRect rightSideFrame = [rightSideView frame];
-    
-    if (NSWidth(leftSideFrame) <= 1.0)
-        leftSideFrame.size.width = 0.0;
-    if (NSWidth(rightSideFrame) <= 1.0)
-        rightSideFrame.size.width = 0.0;
-    
-    mainFrame.size.width = NSWidth([sender frame]) - NSWidth(leftSideFrame) - 
NSWidth(rightSideFrame) - 2 * [sender dividerThickness];
-    
-    if (NSWidth(mainFrame) < 0.0) {
-        float resizeFactor = 1.0 + NSWidth(mainFrame) / 
(NSWidth(leftSideFrame) + NSWidth(rightSideFrame));
-        leftSideFrame.size.width = floorf(resizeFactor * 
NSWidth(leftSideFrame));
-        rightSideFrame.size.width = floorf(resizeFactor * 
NSWidth(rightSideFrame));
+    if ([sender isEqual:splitView]) {
+        NSView *leftSideView = [[sender subviews] objectAtIndex:0];
+        NSView *mainView = [[sender subviews] objectAtIndex:1]; // pdfView
+        NSView *rightSideView = [[sender subviews] objectAtIndex:2];
+        NSRect leftSideFrame = [leftSideView frame];
+        NSRect mainFrame = [mainView frame];
+        NSRect rightSideFrame = [rightSideView frame];
+        
+        if (NSWidth(leftSideFrame) <= 1.0)
+            leftSideFrame.size.width = 0.0;
+        if (NSWidth(rightSideFrame) <= 1.0)
+            rightSideFrame.size.width = 0.0;
+        
         mainFrame.size.width = NSWidth([sender frame]) - 
NSWidth(leftSideFrame) - NSWidth(rightSideFrame) - 2 * [sender 
dividerThickness];
+        
+        if (NSWidth(mainFrame) < 0.0) {
+            float resizeFactor = 1.0 + NSWidth(mainFrame) / 
(NSWidth(leftSideFrame) + NSWidth(rightSideFrame));
+            leftSideFrame.size.width = floorf(resizeFactor * 
NSWidth(leftSideFrame));
+            rightSideFrame.size.width = floorf(resizeFactor * 
NSWidth(rightSideFrame));
+            mainFrame.size.width = NSWidth([sender frame]) - 
NSWidth(leftSideFrame) - NSWidth(rightSideFrame) - 2 * [sender 
dividerThickness];
+        }
+        mainFrame.origin.x = NSMaxX(leftSideFrame) + [sender dividerThickness];
+        rightSideFrame.origin.x =  NSMaxX(mainFrame) + [sender 
dividerThickness];
+        [leftSideView setFrame:leftSideFrame];
+        [rightSideView setFrame:rightSideFrame];
+        [mainView setFrame:mainFrame];
+        
+        [sender adjustSubviews];
+    } else if ([sender isEqual:pdfSplitView]) {
+        NSView *primaryView = [[sender subviews] objectAtIndex:0];
+        NSView *secondaryView = [[sender subviews] objectAtIndex:1];
+        NSRect primaryFrame = [primaryView frame];
+        NSRect secondaryFrame = [secondaryView frame];
+        
+        if (NSHeight(secondaryFrame) <= 1.0)
+            secondaryFrame.size.height = 0.0;
+        
+        primaryFrame.size.height = NSHeight([sender frame]) - 
NSHeight(secondaryFrame)  - [sender dividerThickness];
+        
+        if (NSHeight(primaryFrame) < 0.0) {
+            float resizeFactor = 1.0 + NSHeight(primaryFrame) / 
NSHeight(secondaryFrame);
+            secondaryFrame.size.height = floorf(resizeFactor * 
NSHeight(secondaryFrame));
+            primaryFrame.size.height = NSHeight([sender frame]) - 
NSHeight(secondaryFrame) - 2 * [sender dividerThickness];
+        }
+        primaryFrame.origin.x = NSMaxY(secondaryFrame) + [sender 
dividerThickness];
+        [primaryView setFrame:primaryFrame];
+        [secondaryView setFrame:secondaryFrame];
+        
+        [sender adjustSubviews];
     }
-    mainFrame.origin.x = NSMaxX(leftSideFrame) + [sender dividerThickness];
-    rightSideFrame.origin.x =  NSMaxX(mainFrame) + [sender dividerThickness];
-    [leftSideView setFrame:leftSideFrame];
-    [rightSideView setFrame:rightSideFrame];
-    [mainView setFrame:mainFrame];
-    
-    [sender adjustSubviews];
 }
 
 - (void)splitViewDidResizeSubviews:(NSNotification *)notification {
-    if ([[self window] frameAutosaveName] && settingUpWindow == NO) {
-        [[NSUserDefaults standardUserDefaults] 
setFloat:NSWidth([leftSideContentBox frame]) forKey:SKLeftSidePaneWidthKey];
-        [[NSUserDefaults standardUserDefaults] 
setFloat:NSWidth([rightSideContentBox frame]) forKey:SKRightSidePaneWidthKey];
+    id sender = [notification object];
+    if ([sender isEqual:splitView] || sender == nil) {
+        if ([[self window] frameAutosaveName] && settingUpWindow == NO) {
+            [[NSUserDefaults standardUserDefaults] 
setFloat:NSWidth([leftSideContentBox frame]) forKey:SKLeftSidePaneWidthKey];
+            [[NSUserDefaults standardUserDefaults] 
setFloat:NSWidth([rightSideContentBox frame]) forKey:SKRightSidePaneWidthKey];
+        }
     }
 }
 

Added: trunk/SKSecondaryPDFView.h
===================================================================
--- trunk/SKSecondaryPDFView.h                          (rev 0)
+++ trunk/SKSecondaryPDFView.h  2007-09-19 18:46:18 UTC (rev 2939)
@@ -0,0 +1,61 @@
+//
+//  SKSecondaryPDFView.h
+//  Skim
+//
+//  Created by Christiaan Hofman on 9/19/07.
+/*
+ This software is Copyright (c) 2007
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import <Quartz/Quartz.h>
+
+
[EMAIL PROTECTED] SKSecondaryPDFView : PDFView {
+    NSPopUpButton *scalePopUpButton;
+    NSPopUpButton *pagePopUpButton;
+}
+
+- (void)setAutoScales:(BOOL)newAuto adjustPopup:(BOOL)flag;
+- (void)setScaleFactor:(float)factor adjustPopup:(BOOL)flag;
+- (void)scalePopUpAction:(id)sender;
+- (void)pagePopUpAction:(id)sender;
+- (NSScrollView *)scrollView;
+- (void)layoutScrollView;
+- (void)setScrollerSize:(NSControlSize)controlSize;
+- (void)dragWithEvent:(NSEvent *)theEvent;
+- (void)reloadPagePopUpButton;
+- (void)handlePageChangedNotification:(NSNotification *)notification;
+- (void)handleDocumentDidUnlock:(NSNotification *)notification;
+- (void)setNeedsDisplayForAnnotation:(PDFAnnotation *)annotation 
onPage:(PDFPage *)page;
+
[EMAIL PROTECTED]

Added: trunk/SKSecondaryPDFView.m
===================================================================
--- trunk/SKSecondaryPDFView.m                          (rev 0)
+++ trunk/SKSecondaryPDFView.m  2007-09-19 18:46:18 UTC (rev 2939)
@@ -0,0 +1,489 @@
+//
+//  SKSecondaryPDFView.m
+//  Skim
+//
+//  Created by Christiaan Hofman on 9/19/07.
+/*
+ This software is Copyright (c) 2007
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SKSecondaryPDFView.h"
+#import "BDSKHeaderPopUpButton.h"
+#import "NSScrollView_SKExtensions.h"
+
+
[EMAIL PROTECTED] PDFView (SKApplePrivateOverride)
+- (void)adjustScrollbars:(id)obj;
[EMAIL PROTECTED]
+
[EMAIL PROTECTED] SKSecondaryPDFView
+
+/* For genstrings:
+    NSLocalizedStringFromTable(@"Auto", @"ZoomValues", @"Zoom popup entry")
+    NSLocalizedStringFromTable(@"10%", @"ZoomValues", @"Zoom popup entry")
+    NSLocalizedStringFromTable(@"25%", @"ZoomValues", @"Zoom popup entry")
+    NSLocalizedStringFromTable(@"50%", @"ZoomValues", @"Zoom popup entry")
+    NSLocalizedStringFromTable(@"75%", @"ZoomValues", @"Zoom popup entry")
+    NSLocalizedStringFromTable(@"100%", @"ZoomValues", @"Zoom popup entry")
+    NSLocalizedStringFromTable(@"128%", @"ZoomValues", @"Zoom popup entry")
+    NSLocalizedStringFromTable(@"200%", @"ZoomValues", @"Zoom popup entry")
+    NSLocalizedStringFromTable(@"400%", @"ZoomValues", @"Zoom popup entry")
+    NSLocalizedStringFromTable(@"800%", @"ZoomValues", @"Zoom popup entry")
+*/   
+static NSString *SKDefaultScaleMenuLabels[] = {/* @"Set...", */ @"Auto", 
@"10%", @"25%", @"50%", @"75%", @"100%", @"128%", @"150%", @"200%", @"400%", 
@"800%"};
+static float SKDefaultScaleMenuFactors[] = {/* 0.0, */ 0, 0.1, 0.25, 0.5, 
0.75, 1.0, 1.28, 1.5, 2.0, 4.0, 8.0};
+static float SKPopUpMenuFontSize = 11.0;
+
+
+- (id)initWithFrame:(NSRect)frameRect {
+    if (self = [super initWithFrame:frameRect]) {
+        scalePopUpButton = nil;
+        pagePopUpButton = nil;
+        [[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(handlePageChangedNotification:) 
+                                                     
name:PDFViewPageChangedNotification object:self];
+    }
+    return self;
+}
+
+- (id)initWithCoder:(NSCoder *)decoder {
+    if (self = [super initWithCoder:decoder]) {
+        scalePopUpButton = nil;
+        pagePopUpButton = nil;
+        [[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(handlePageChangedNotification:) 
+                                                     
name:PDFViewPageChangedNotification object:self];
+    }
+    return self;
+}
+
+- (void)setDocument:(PDFDocument *)document {
+    if ([self document])
+        [[NSNotificationCenter defaultCenter] removeObserver:self 
name:PDFViewPageChangedNotification object:[self document]];
+    [super setDocument:document];
+    [self reloadPagePopUpButton];
+    if (document && [document isLocked])
+        [[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(handleDocumentDidUnlockNotification:) 
+                                                     
name:PDFDocumentDidUnlockNotification object:document];
+}
+
+- (void)drawRect:(NSRect)rect {
+    [self layoutScrollView];
+    [super drawRect:rect];
+
+    if ([scalePopUpButton superview]) {
+        NSRect shadowRect = NSUnionRect([scalePopUpButton frame], 
[pagePopUpButton frame]);
+        shadowRect.origin.x -= 1.0;
+        shadowRect.origin.y -= 1.0;
+        shadowRect.size.width += 1.0;
+        shadowRect.size.height += 1.0;
+               shadowRect = [self convertRect:shadowRect 
fromView:[scalePopUpButton superview]];
+        if (NSIntersectsRect(rect, shadowRect)) {
+            [[NSColor lightGrayColor] set];
+            NSRectFill(shadowRect);
+        }
+    }
+}
+
+- (void)setNeedsDisplayForAnnotation:(PDFAnnotation *)annotation 
onPage:(PDFPage *)page {
+    NSRect rect = [self convertRect:[page boundsForBox:kPDFDisplayBoxCropBox] 
fromPage:page];
+    float scale = [self scaleFactor];
+    float maxX = ceilf(NSMaxX(rect) + scale);
+    float maxY = ceilf(NSMaxY(rect) + scale);
+    float minX = floorf(NSMinX(rect) - scale);
+    float minY = floorf(NSMinY(rect) - scale);
+    rect = NSIntersectionRect([self bounds], NSMakeRect(minX, minY, maxX - 
minX, maxY - minY));
+    if (NSIsEmptyRect(rect) == NO)
+        [self setNeedsDisplayInRect:rect];
+}
+
+#pragma mark Popup buttons
+
+- (void)makeScalePopUpButton {
+    
+    if (scalePopUpButton == nil) {
+        
+        NSScrollView *scrollView = [self scrollView];
+        [scrollView setAlwaysHasHorizontalScroller:YES];
+
+        unsigned cnt, numberOfDefaultItems = (sizeof(SKDefaultScaleMenuLabels) 
/ sizeof(NSString *));
+        id curItem;
+
+        // create it        
+        scalePopUpButton = [[BDSKHeaderPopUpButton allocWithZone:[self zone]] 
initWithFrame:NSMakeRect(0.0, 0.0, 1.0, 1.0) pullsDown:NO];
+        
+        NSControlSize controlSize = [[scrollView horizontalScroller] 
controlSize];
+        [[scalePopUpButton cell] setControlSize:controlSize];
+               
+        // fill it
+        for (cnt = 0; cnt < numberOfDefaultItems; cnt++) {
+            [scalePopUpButton 
addItemWithTitle:NSLocalizedStringFromTable(SKDefaultScaleMenuLabels[cnt], 
@"ZoomValues", nil)];
+            curItem = [scalePopUpButton itemAtIndex:cnt];
+            [curItem setRepresentedObject:(SKDefaultScaleMenuFactors[cnt] > 
0.0 ? [NSNumber numberWithFloat:SKDefaultScaleMenuFactors[cnt]] : nil)];
+        }
+        // select the appropriate item, adjusting the scaleFactor if necessary
+        if([self autoScales])
+            [self setScaleFactor:0.0 adjustPopup:YES];
+        else
+            [self setScaleFactor:[self scaleFactor] adjustPopup:YES];
+
+        // hook it up
+        [scalePopUpButton setTarget:self];
+        [scalePopUpButton setAction:@selector(scalePopUpAction:)];
+
+        // set a suitable font, the control size is 0, 1 or 2
+        [scalePopUpButton setFont:[NSFont toolTipsFontOfSize: 
SKPopUpMenuFontSize - controlSize]];
+
+        // Make sure the popup is big enough to fit the cells.
+        [scalePopUpButton sizeToFit];
+
+               // don't let it become first responder
+               [scalePopUpButton setRefusesFirstResponder:YES];
+
+        // put it in the scrollview
+        [scrollView addSubview:scalePopUpButton];
+        [scalePopUpButton release];
+    }
+}
+
+- (void)reloadPagePopUpButton {
+    PDFDocument *pdfDoc = [self document];
+    unsigned i, count = [pagePopUpButton numberOfItems];
+    NSString *label;
+    float width, maxWidth = 0.0;
+    NSSize size = NSMakeSize(1000.0, 1000.0);
+    NSDictionary *attrs = [[pagePopUpButton attributedTitle] 
attributesAtIndex:0 effectiveRange:NULL];
+    unsigned maxIndex = 0;
+    
+    while (count--)
+        [pagePopUpButton removeItemAtIndex:count];
+    
+    count = [pdfDoc pageCount];
+    for (i = 0; i < count; i++) {
+        label = [[pdfDoc pageAtIndex:i] label];
+        if (label == nil)
+            label = [NSString stringWithFormat:@"%i", i + 1];
+        width = NSWidth([label boundingRectWithSize:size options:0 
attributes:attrs]);
+        if (width > maxWidth) {
+            maxWidth = width;
+            maxIndex = i;
+        }
+        [pagePopUpButton addItemWithTitle:label];
+    }
+    
+    [pagePopUpButton setTitle:[[pagePopUpButton itemAtIndex:maxIndex] title]];
+    [pagePopUpButton sizeToFit];
+    [pagePopUpButton synchronizeTitleAndSelectedItem];
+    
+    [pagePopUpButton selectItemAtIndex:[pdfDoc indexForPage:[self 
currentPage]]];
+}
+
+- (void)makePagePopUpButton {
+    
+    if (pagePopUpButton == nil) {
+        
+        NSScrollView *scrollView = [self scrollView];
+        [scrollView setAlwaysHasHorizontalScroller:YES];
+        
+        // create it        
+        pagePopUpButton = [[BDSKHeaderPopUpButton allocWithZone:[self zone]] 
initWithFrame:NSMakeRect(0.0, 0.0, 1.0, 1.0) pullsDown:NO];
+        
+        NSControlSize controlSize = [[scrollView horizontalScroller] 
controlSize];
+        [[pagePopUpButton cell] setControlSize:controlSize];
+
+        // set a suitable font, the control size is 0, 1 or 2
+        [pagePopUpButton setFont:[NSFont toolTipsFontOfSize: 
SKPopUpMenuFontSize - controlSize]];
+               
+        [self reloadPagePopUpButton];
+
+               // don't let it become first responder
+               [pagePopUpButton setRefusesFirstResponder:YES];
+        
+        // hook it up
+        [pagePopUpButton setTarget:self];
+        [pagePopUpButton setAction:@selector(pagePopUpAction:)];
+
+        // put it in the scrollview
+        [scrollView addSubview:pagePopUpButton];
+        [pagePopUpButton release];
+    }
+}
+
+- (void)scalePopUpAction:(id)sender {
+    NSNumber *selectedFactorObject = [[sender selectedItem] representedObject];
+    if(selectedFactorObject)
+        [self setScaleFactor:[selectedFactorObject floatValue] adjustPopup:NO];
+    else
+        [self setAutoScales:YES adjustPopup:NO];
+}
+
+- (void)pagePopUpAction:(id)sender {
+    [self goToPage:[[self document] pageAtIndex:[sender indexOfSelectedItem]]];
+}
+
+- (void)setAutoScales:(BOOL)newAuto {
+    [self setAutoScales:newAuto adjustPopup:YES];
+}
+
+- (void)setAutoScales:(BOOL)newAuto adjustPopup:(BOOL)flag {
+    if ([self autoScales] != newAuto) {
+        [super setAutoScales:newAuto];
+        if (newAuto && flag)
+            [scalePopUpButton selectItemAtIndex:0];
+    }
+}
+
+- (void)setScaleFactor:(float)newScaleFactor {
+       [self setScaleFactor:newScaleFactor adjustPopup:YES];
+}
+
+- (void)setScaleFactor:(float)newScaleFactor adjustPopup:(BOOL)flag {
+    
+       if (flag) {
+               if (newScaleFactor < 0.01) {
+            newScaleFactor = 0.0;
+        } else {
+            unsigned cnt = 1, numberOfDefaultItems = 
(sizeof(SKDefaultScaleMenuFactors) / sizeof(float));
+            
+            // We only work with some preset zoom values, so choose one of the 
appropriate values
+            while (cnt < numberOfDefaultItems - 1 && newScaleFactor > 0.5 * 
(SKDefaultScaleMenuFactors[cnt] + SKDefaultScaleMenuFactors[cnt + 1])) cnt++;
+            [scalePopUpButton selectItemAtIndex:cnt];
+            newScaleFactor = SKDefaultScaleMenuFactors[cnt];
+        }
+    }
+    
+    if (newScaleFactor < 0.01) {
+        [self setAutoScales:YES];
+    } else {
+        [self setAutoScales:NO adjustPopup:NO];
+        [super setScaleFactor:newScaleFactor];
+    }
+}
+
+- (IBAction)zoomIn:(id)sender{
+    int cnt = 0, numberOfDefaultItems = (sizeof(SKDefaultScaleMenuFactors) / 
sizeof(float));
+    float scaleFactor = [self scaleFactor];
+    
+    // We only work with some preset zoom values, so choose one of the 
appropriate values (Fudge a little for floating point == to work)
+    while (cnt < numberOfDefaultItems && scaleFactor * .99 > 
SKDefaultScaleMenuFactors[cnt]) cnt++;
+    cnt++;
+    while (cnt >= numberOfDefaultItems) cnt--;
+    [self setScaleFactor:SKDefaultScaleMenuFactors[cnt]];
+}
+
+- (IBAction)zoomOut:(id)sender{
+    int cnt = 0, numberOfDefaultItems = (sizeof(SKDefaultScaleMenuFactors) / 
sizeof(float));
+    float scaleFactor = [self scaleFactor];
+    
+    // We only work with some preset zoom values, so choose one of the 
appropriate values (Fudge a little for floating point == to work)
+    while (cnt < numberOfDefaultItems && scaleFactor * .99 > 
SKDefaultScaleMenuFactors[cnt]) cnt++;
+    cnt--;
+    if (cnt < 0) cnt++;
+    [self setScaleFactor:SKDefaultScaleMenuFactors[cnt]];
+}
+
+- (BOOL)canZoomIn{
+    if ([super canZoomIn] == NO)
+        return NO;
+    unsigned cnt = 0, numberOfDefaultItems = 
(sizeof(SKDefaultScaleMenuFactors) / sizeof(float));
+    float scaleFactor = [self scaleFactor];
+    // We only work with some preset zoom values, so choose one of the 
appropriate values (Fudge a little for floating point == to work)
+    while (cnt < numberOfDefaultItems && scaleFactor * .99 > 
SKDefaultScaleMenuFactors[cnt]) cnt++;
+    return cnt < numberOfDefaultItems - 1;
+}
+
+- (BOOL)canZoomOut{
+    if ([super canZoomOut] == NO)
+        return NO;
+    unsigned cnt = 0, numberOfDefaultItems = 
(sizeof(SKDefaultScaleMenuFactors) / sizeof(float));
+    float scaleFactor = [self scaleFactor];
+    // We only work with some preset zoom values, so choose one of the 
appropriate values (Fudge a little for floating point == to work)
+    while (cnt < numberOfDefaultItems && scaleFactor * .99 > 
SKDefaultScaleMenuFactors[cnt]) cnt++;
+    return cnt > 0;
+}
+
+#pragma mark Scrollview
+
+- (NSScrollView *)scrollView;
+{
+    return [[self documentView] enclosingScrollView];
+}
+
+- (void)setScrollerSize:(NSControlSize)controlSize;
+{
+    NSScrollView *scrollView = [[self documentView] enclosingScrollView];
+    [scrollView setHasHorizontalScroller:YES];
+    [scrollView setHasVerticalScroller:YES];
+    [[scrollView horizontalScroller] setControlSize:controlSize];
+    [[scrollView verticalScroller] setControlSize:controlSize];
+       if (scalePopUpButton) {
+               [[scalePopUpButton cell] setControlSize:controlSize];
+        [scalePopUpButton setFont:[NSFont toolTipsFontOfSize: 
SKPopUpMenuFontSize - controlSize]];
+       }
+       if (pagePopUpButton) {
+               [[pagePopUpButton cell] setControlSize:controlSize];
+        [pagePopUpButton setFont:[NSFont toolTipsFontOfSize: 
SKPopUpMenuFontSize - controlSize]];
+       }
+}
+
+- (void)adjustScrollbars:(id)obj;
+{
+    // this private method is only called by PDFView, so super must implement 
it if it's called
+    [super adjustScrollbars:obj];
+    [self layoutScrollView];
+    // be careful here; check the comment in -layoutScrollView before changing 
anything
+}
+
+- (void)layoutScrollView;
+{
+    NSScrollView *scrollView = [self scrollView];
+    
+    // Don't force scroller display on the scrollview; PDFView apparently uses 
a timer to call adjustScrollbars:, and preventing autohide will cause an 
endless loop if you zoom so that the vertical scroller is not displayed 
(regardless of whether we swizzle -[NSScrollView tile] or override -[PDFView 
adjustScrollbars:]).  Therefore, we always display the button,  even though it 
looks stupid without the scrollers.  Since it's not really readable anyway at 
25%, this probably isn't a big deal, since this isn't supposed to be a 
thumbnail view.
+    
+    NSControlSize controlSize = NSRegularControlSize;
+    
+    if ([scrollView hasHorizontalScroller])
+        controlSize = [[scrollView horizontalScroller] controlSize];
+    else if ([scrollView hasVerticalScroller])
+        controlSize = [[scrollView verticalScroller] controlSize];
+    
+    float scrollerWidth = [NSScroller scrollerWidthForControlSize:controlSize];
+    
+    if (scalePopUpButton == nil)
+        [self makeScalePopUpButton];
+    if (pagePopUpButton == nil)
+        [self makePagePopUpButton];
+    
+    NSRect horizScrollerFrame, scaleButtonFrame, pageButtonFrame;
+    scaleButtonFrame = [scalePopUpButton frame];
+    pageButtonFrame = [pagePopUpButton frame];
+    
+    NSScroller *horizScroller = [scrollView horizontalScroller];
+    
+    if (horizScroller) {
+        horizScrollerFrame = [horizScroller frame];
+        
+        // Now we'll just adjust the horizontal scroller size and set the 
button size and location.
+        // Set it based on our frame, not the scroller's frame, since this 
gets called repeatedly.
+        horizScrollerFrame.size.width = NSWidth([scrollView frame]) - 
NSWidth(scaleButtonFrame) - NSWidth(pageButtonFrame) - scrollerWidth - 1.0;
+        [horizScroller setFrameSize:horizScrollerFrame.size];
+    }
+    scaleButtonFrame.size.height = scrollerWidth - 1.0;
+    pageButtonFrame.size.height = scrollerWidth - 1.0;
+
+    if ([scrollView isFlipped]) {
+        scaleButtonFrame.origin.x = NSMaxX([scrollView frame]) - scrollerWidth 
- NSWidth(scaleButtonFrame);
+        scaleButtonFrame.origin.y = NSMaxY([scrollView frame]) - 
NSHeight(scaleButtonFrame);            
+        pageButtonFrame.origin.x = NSMinX(scaleButtonFrame) - 
NSWidth(pageButtonFrame);
+        pageButtonFrame.origin.y = NSMaxY([scrollView frame]) - 
NSHeight(pageButtonFrame);            
+    }
+    else {
+        scaleButtonFrame.origin.x = NSMaxX([scrollView frame]) - scrollerWidth 
- NSWidth(scaleButtonFrame);
+        scaleButtonFrame.origin.y = NSMinY([scrollView frame]);
+        pageButtonFrame.origin.x = NSMinX(scaleButtonFrame) - 
NSWidth(pageButtonFrame);
+        pageButtonFrame.origin.y = NSMinY([scrollView frame]);
+    }
+    [scalePopUpButton setFrame:scaleButtonFrame];
+    [pagePopUpButton setFrame:pageButtonFrame];
+}
+
+#pragma mark Dragging
+
+- (void)mouseDown:(NSEvent *)theEvent{
+    [[NSCursor closedHandCursor] push];
+}
+
+- (void)mouseUp:(NSEvent *)theEvent{
+    [NSCursor pop];
+    [self mouseMoved:theEvent];
+}
+
+- (void)mouseMoved:(NSEvent *)theEvent {
+       NSPoint mouseLoc = [[self documentView] convertPoint:[theEvent 
locationInWindow] fromView:nil];
+    if (NSPointInRect(mouseLoc, [[self documentView] visibleRect]))
+        [[NSCursor openHandCursor] set];
+    else
+        [[NSCursor arrowCursor] set];
+}
+
+- (void)mouseDragged:(NSEvent *)theEvent {
+    [self dragWithEvent:theEvent];     
+    // ??? PDFView's delayed layout seems to reset the cursor to an arrow
+    [self performSelector:@selector(mouseMoved:) withObject:theEvent 
afterDelay:0];
+}
+
+- (void)dragWithEvent:(NSEvent *)theEvent {
+       NSPoint initialLocation = [theEvent locationInWindow];
+       NSRect visibleRect = [[self documentView] visibleRect];
+       BOOL keepGoing = YES;
+       
+       while (keepGoing) {
+               theEvent = [[self window] nextEventMatchingMask: 
NSLeftMouseUpMask | NSLeftMouseDraggedMask];
+               switch ([theEvent type]) {
+                       case NSLeftMouseDragged:
+            {
+                               NSPoint newLocation;
+                               NSRect  newVisibleRect;
+                               float   xDelta, yDelta;
+                               
+                               newLocation = [theEvent locationInWindow];
+                               xDelta = initialLocation.x - newLocation.x;
+                               yDelta = initialLocation.y - newLocation.y;
+                               if ([self isFlipped])
+                                       yDelta = -yDelta;
+                               
+                               newVisibleRect = NSOffsetRect (visibleRect, 
xDelta, yDelta);
+                               [[self documentView] scrollRectToVisible: 
newVisibleRect];
+                       }
+                               break;
+                               
+                       case NSLeftMouseUp:
+                               keepGoing = NO;
+                               break;
+                               
+                       default:
+                               /* Ignore any other kind of event. */
+                               break;
+               } // end of switch (event type)
+       } // end of mouse-tracking loop
+}
+
+#pragma mark Notification handling
+
+- (void)handlePageChangedNotification:(NSNotification *)notification {
+    [pagePopUpButton selectItemAtIndex:[[self document] indexForPage:[self 
currentPage]]];
+}
+
+- (void)handleDocumentDidUnlock:(NSNotification *)notification {
+    [self reloadPagePopUpButton];
+    [self layoutScrollView];
+}
+
[EMAIL PROTECTED]

Modified: trunk/SKSplitView.h
===================================================================
--- trunk/SKSplitView.h 2007-09-19 16:40:23 UTC (rev 2938)
+++ trunk/SKSplitView.h 2007-09-19 18:46:18 UTC (rev 2939)
@@ -40,9 +40,13 @@
 
 @class CIColor;
 
[EMAIL PROTECTED] SKSplitView : NSSplitView
[EMAIL PROTECTED] SKSplitView : NSSplitView {
+    BOOL blendEnds;
+}
 + (CIColor *)startColor;
 + (CIColor *)endColor;
+- (BOOL)blendEnds;
+- (void)setBlendEnds:(BOOL)flag;
 @end
 
 @interface NSObject (SKSplitViewExtendedDelegate)

Modified: trunk/SKSplitView.m
===================================================================
--- trunk/SKSplitView.m 2007-09-19 16:40:23 UTC (rev 2938)
+++ trunk/SKSplitView.m 2007-09-19 18:46:18 UTC (rev 2939)
@@ -40,6 +40,7 @@
 #import "NSBezierPath_CoreImageExtensions.h"
 #import "CIImage_BDSKExtensions.h"
 
+#define END_JOIN_WIDTH 3.0f
 
 @implementation SKSplitView
 
@@ -85,6 +86,33 @@
     [super mouseDown:theEvent];
 }
 
+- (void)drawBlendedJoinEndAtLeftInRect:(NSRect)rect {
+    // this blends us smoothly with the a vertical divider on our left
+    Class svClass = [self class];
+    [[NSBezierPath bezierPathWithRect:rect] fillPathWithColor:[svClass 
startColor]
+                                               blendedAtRight:NO
+                                  ofVerticalGradientFromColor:[svClass 
startColor]
+                                                      toColor:[svClass 
endColor]];
+}
+
+- (void)drawBlendedJoinEndAtRightInRect:(NSRect)rect {
+    // this blends us smoothly with the a vertical divider on our right
+    Class svClass = [self class];
+    [[NSBezierPath bezierPathWithRect:rect] fillPathWithColor:[svClass 
endColor]
+                                               blendedAtRight:YES
+                                  ofVerticalGradientFromColor:[svClass 
startColor]
+                                                      toColor:[svClass 
endColor]];
+}
+
+- (void)drawBlendedJoinEndAtTopInRect:(NSRect)rect {
+    // this blends us smoothly with the a vertical divider on our left
+    Class svClass = [self class];
+    [[NSBezierPath bezierPathWithRect:rect] fillPathWithColor:[svClass 
startColor]
+                                               blendedAtRight:NO
+                                  ofVerticalGradientFromColor:[svClass 
startColor]
+                                                      toColor:[svClass 
endColor]];
+}
+
 - (void)drawDividerInRect:(NSRect)aRect {
     NSPoint startPoint, endPoint;
     float handleSize = 20.0;
@@ -94,6 +122,14 @@
     // Draw the gradient
     [[NSBezierPath bezierPathWithRect:aRect] fillPathVertically:NO == [self 
isVertical] withStartColor:[[self class] startColor] endColor:[[self class] 
endColor]];
     
+    if (blendEnds && [self isVertical] == NO) {
+        NSRect endRect, ignored;
+        NSDivideRect(aRect, &endRect, &ignored, END_JOIN_WIDTH, NSMinXEdge);
+        [self drawBlendedJoinEndAtLeftInRect:endRect];
+        NSDivideRect(aRect, &endRect, &ignored, END_JOIN_WIDTH, NSMaxXEdge);
+        [self drawBlendedJoinEndAtRightInRect:endRect];
+    }
+    
     [NSGraphicsContext saveGraphicsState];
     
     // Draw the handle
@@ -140,4 +176,12 @@
        return 6.0;
 }
 
+- (BOOL)blendEnds {
+    return blendEnds;
+}
+
+- (void)setBlendEnds:(BOOL)flag {
+    blendEnds = flag;
+}
+
 @end

Modified: trunk/Skim.xcodeproj/project.pbxproj
===================================================================
--- trunk/Skim.xcodeproj/project.pbxproj        2007-09-19 16:40:23 UTC (rev 
2938)
+++ trunk/Skim.xcodeproj/project.pbxproj        2007-09-19 18:46:18 UTC (rev 
2939)
@@ -168,6 +168,8 @@
                CEAA56D50C6DEE83006BD633 /* Delete.tiff in Resources */ = {isa 
= PBXBuildFile; fileRef = CEAA56D30C6DEE83006BD633 /* Delete.tiff */; };
                CEAA67260C70A882006BD633 /* NSURL_SKExtensions.m in Sources */ 
= {isa = PBXBuildFile; fileRef = CEAA67240C70A882006BD633 /* 
NSURL_SKExtensions.m */; };
                CEAA68EB0C71242F006BD633 /* Resume.tiff in Resources */ = {isa 
= PBXBuildFile; fileRef = CEAA68EA0C71242F006BD633 /* Resume.tiff */; };
+               CEAE1C470CA1877F00849B0F /* SKSecondaryPDFView.h in CopyFiles 
*/ = {isa = PBXBuildFile; fileRef = CEAE1C450CA1877F00849B0F /* 
SKSecondaryPDFView.h */; };
+               CEAE1C480CA1877F00849B0F /* SKSecondaryPDFView.m in Sources */ 
= {isa = PBXBuildFile; fileRef = CEAE1C460CA1877F00849B0F /* 
SKSecondaryPDFView.m */; };
                CEAF079D0C4139EB00C3ECBB /* SKStatusBar.m in Sources */ = {isa 
= PBXBuildFile; fileRef = CEAF079B0C4139EB00C3ECBB /* SKStatusBar.m */; };
                CEAF2E5A0C45414100C3ECBB /* SKLine.m in Sources */ = {isa = 
PBXBuildFile; fileRef = CEAF2E580C45414100C3ECBB /* SKLine.m */; };
                CEAFFD7C0C40ED5400C3ECBB /* ToolbarColors.tiff in Resources */ 
= {isa = PBXBuildFile; fileRef = CEAFFD7A0C40ED5400C3ECBB /* ToolbarColors.tiff 
*/; };
@@ -274,6 +276,7 @@
                        dstSubfolderSpec = 10;
                        files = (
                                CE2BD8450BD4135600A5F4DB /* Sparkle.framework 
in CopyFiles */,
+                               CEAE1C470CA1877F00849B0F /* 
SKSecondaryPDFView.h in CopyFiles */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
@@ -572,6 +575,8 @@
                CEAA67230C70A882006BD633 /* NSURL_SKExtensions.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
NSURL_SKExtensions.h; sourceTree = "<group>"; };
                CEAA67240C70A882006BD633 /* NSURL_SKExtensions.m */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path 
= NSURL_SKExtensions.m; sourceTree = "<group>"; };
                CEAA68EA0C71242F006BD633 /* Resume.tiff */ = {isa = 
PBXFileReference; lastKnownFileType = image.tiff; name = Resume.tiff; path = 
Images/Resume.tiff; sourceTree = "<group>"; };
+               CEAE1C450CA1877F00849B0F /* SKSecondaryPDFView.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
SKSecondaryPDFView.h; sourceTree = "<group>"; };
+               CEAE1C460CA1877F00849B0F /* SKSecondaryPDFView.m */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path 
= SKSecondaryPDFView.m; sourceTree = "<group>"; };
                CEAF079A0C4139EB00C3ECBB /* SKStatusBar.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
SKStatusBar.h; sourceTree = "<group>"; };
                CEAF079B0C4139EB00C3ECBB /* SKStatusBar.m */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path 
= SKStatusBar.m; sourceTree = "<group>"; };
                CEAF2E570C45414100C3ECBB /* SKLine.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
SKLine.h; sourceTree = "<group>"; };
@@ -974,6 +979,8 @@
                                4530DCF60B27CACE007C59F4 /* SKPDFView.m */,
                                CEAA55B40C6DE452006BD633 /* SKProgressCell.h */,
                                CEAA55B50C6DE452006BD633 /* SKProgressCell.m */,
+                               CEAE1C450CA1877F00849B0F /* 
SKSecondaryPDFView.h */,
+                               CEAE1C460CA1877F00849B0F /* 
SKSecondaryPDFView.m */,
                                CE4EC88A0B7E6EDB0091F228 /* SKSplitView.h */,
                                CE4EC88B0B7E6EDB0091F228 /* SKSplitView.m */,
                                CEAF079A0C4139EB00C3ECBB /* SKStatusBar.h */,
@@ -1558,6 +1565,7 @@
                                CEBD52ED0C9C0AE500FBF6A4 /* SKBookmark.m in 
Sources */,
                                CE209FAA0C9D38C6007C72F9 /* 
SKProgressController.m in Sources */,
                                CE20B1950C9F23CC007C72F9 /* 
NSView_SKExtensions.m in Sources */,
+                               CEAE1C480CA1877F00849B0F /* 
SKSecondaryPDFView.m in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit

Reply via email to