Revision: 28657
          http://sourceforge.net/p/bibdesk/svn/28657
Author:   hofman
Date:     2024-01-23 17:45:32 +0000 (Tue, 23 Jan 2024)
Log Message:
-----------
Add arrow buttons as subviews. Avoids redrawing the icons.

Modified Paths:
--------------
    trunk/bibdesk_vendorsrc/amaxwell/FileView/FVArrowButtonCell.h
    trunk/bibdesk_vendorsrc/amaxwell/FileView/FVArrowButtonCell.m
    trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.h
    trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m

Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVArrowButtonCell.h
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVArrowButtonCell.h       
2024-01-23 15:28:04 UTC (rev 28656)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVArrowButtonCell.h       
2024-01-23 17:45:32 UTC (rev 28657)
@@ -45,11 +45,21 @@
     FVArrowLeft  = 1
 };
 
+@interface FVArrowButton : NSButton {
+}
+
+- (id)initWithArrowDirection:(FVArrowDirection)anArrowDirection;
+
+@property (nonatomic) CGFloat arrowAlpha;
+
+@end
+
 /** @internal @brief Circular arrow button.
  
  FVArrowButtonCell is a circle with an arrow inside, used as a page change 
button.  Modeled after the page change button that Finder shows for PDF files 
on 10.5 in column mode preview.  */
 @interface FVArrowButtonCell : NSButtonCell {
     FVArrowDirection _arrowDirection;
+    CGFloat _arrowAlpha;
 }
 
 /** Designated initializer.
@@ -67,6 +77,8 @@
  @param alpha 1.0 for opaque, 0.0 for transparent. */
 - (void)drawWithFrame:(NSRect)frame inView:(NSView *)controlView 
alpha:(CGFloat)alpha;
 
+@property (nonatomic) CGFloat arrowAlpha;
+
 @end
 
 /** @typedef NSUInteger FVArrowDirection 

Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVArrowButtonCell.m
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVArrowButtonCell.m       
2024-01-23 15:28:04 UTC (rev 28656)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVArrowButtonCell.m       
2024-01-23 17:45:32 UTC (rev 28657)
@@ -37,6 +37,7 @@
  */
 
 #import "FVArrowButtonCell.h"
+#import <QuartzCore/QuartzCore.h>
 
 #if !defined(MAC_OS_X_VERSION_10_12) || MAC_OS_X_VERSION_MAX_ALLOWED < 
MAC_OS_X_VERSION_10_12
 #define NSEventMaskLeftMouseUp NSLeftMouseUpMask
@@ -44,9 +45,40 @@
 #define NSEventTypeLeftMouseDragged NSLeftMouseDragged
 #endif
 
+@implementation FVArrowButton
+
+@dynamic arrowAlpha;
+
++ (id)defaultAnimationForKey:(NSAnimatablePropertyKey)key {
+    if ([key isEqualToString:@"arrowAlpha"])
+        return [CABasicAnimation animation];
+    return [super defaultAnimationForKey:key];
+}
+
++ (Class)cellClass { return [FVArrowButtonCell self]; }
+
+- (id)initWithArrowDirection:(FVArrowDirection)anArrowDirection {
+    self = [super initWithFrame:NSZeroRect];
+    if (self) {
+        [self setCell:[[FVArrowButtonCell alloc] 
initWithArrowDirection:anArrowDirection]];
+    }
+    return self;
+}
+
+- (CGFloat)arrowAlpha {
+    return [(FVArrowButtonCell *)[self cell] arrowAlpha];
+}
+
+- (void)setArrowAlpha:(CGFloat)arrowAlpha {
+    [(FVArrowButtonCell *)[self cell] setArrowAlpha:arrowAlpha];
+    [self setNeedsDisplay:YES];
+}
+
+@end
+
 @implementation FVArrowButtonCell
 
-+ (BOOL)prefersTrackingUntilMouseUp { return YES; }
+@synthesize arrowAlpha=_arrowAlpha;
 
 - (id)initTextCell:(NSString *)aString {
     return [self initWithArrowDirection:FVArrowRight];
@@ -61,6 +93,7 @@
         [self setBordered:NO];
         [self setContinuous:YES];
         _arrowDirection = anArrowDirection;
+        _arrowAlpha = 1.0;
     }
     return self;
 }
@@ -91,7 +124,7 @@
 
 - (void)drawWithFrame:(NSRect)frame inView:(NSView *)controlView;
 {
-    [self drawWithFrame:frame inView:controlView alpha:1.0];
+    [self drawWithFrame:frame inView:controlView alpha:_arrowAlpha];
 }
 
 - (void)drawWithFrame:(NSRect)frame inView:(NSView *)controlView 
alpha:(CGFloat)alpha;
@@ -134,30 +167,4 @@
     CGContextRestoreGState(ctxt);
 }
 
-- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView 
*)controlView untilMouseUp:(BOOL)untilMouseUp {
-    NSPoint mouseLoc = [controlView convertPoint:[theEvent locationInWindow] 
fromView:nil];
-    BOOL isInside = NSMouseInRect(mouseLoc, cellFrame, [controlView 
isFlipped]);
-    if (isInside) {
-               BOOL keepOn = YES;
-               while (keepOn) {
-            if (isInside) {
-                // NSButtonCell does not highlight itself, it tracks until a 
click or the mouse exits
-                [self highlight:YES withFrame:cellFrame inView:controlView];
-                isInside = [super trackMouse:theEvent inRect:cellFrame 
ofView:controlView untilMouseUp:NO];
-                [self highlight:NO withFrame:cellFrame inView:controlView];
-                keepOn = isInside ? NO : untilMouseUp;
-            }
-            if (keepOn) {
-                // we're dragging outside the button, wait for a mouseup or 
move back inside
-                theEvent = [[controlView window] nextEventMatchingMask: 
NSEventMaskLeftMouseUp | NSEventMaskLeftMouseDragged];
-                mouseLoc = [controlView convertPoint:[theEvent 
locationInWindow] fromView:nil];
-                isInside = NSMouseInRect(mouseLoc, cellFrame, [controlView 
isFlipped]);
-                keepOn = ([theEvent type] == NSEventTypeLeftMouseDragged);
-            }
-               }
-        return isInside;
-    } else 
-        return NO;
-}
-
 @end

Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.h
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.h      2024-01-23 
15:28:04 UTC (rev 28656)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.h      2024-01-23 
17:45:32 UTC (rev 28657)
@@ -194,7 +194,7 @@
 @end
 
 
-@class FVSliderWindow, FVOperationQueue, FVBackgroundView;
+@class FVSliderWindow, FVOperationQueue, FVBackgroundView, FVArrowButton;
 
 /**
  FVFileView is the primary class in the framework.  
@@ -231,7 +231,6 @@
         unsigned int isRescaling:1;
         unsigned int scheduledLiveResize:1;
         unsigned int updatingFromSlider:1;
-        unsigned int hasArrows:1;
         unsigned int needsReload:1;
         unsigned int controllingSharedPreviewer:1;
         unsigned int controllingQLPreviewPanel:1;
@@ -246,11 +245,8 @@
     NSTextFieldCell                *_titleCell;
     NSTextFieldCell                *_subtitleCell;
     NSMutableArray                 *_trackingAreas;
-    NSButtonCell                   *_leftArrow;
-    NSButtonCell                   *_rightArrow;
-    NSRect                          _leftArrowFrame;
-    NSRect                          _rightArrowFrame;
-    CGFloat                         _arrowAlpha;
+    FVArrowButton                  *_leftArrow;
+    FVArrowButton                  *_rightArrow;
     FVSliderWindow                 *_sliderWindow;
     NSTrackingArea                 *_topSliderArea;
     NSTrackingArea                 *_bottomSliderArea;

Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m      2024-01-23 
15:28:04 UTC (rev 28656)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m      2024-01-23 
17:45:32 UTC (rev 28657)
@@ -211,8 +211,6 @@
 
 @property (nonatomic, copy) NSArray *iconURLs;
 
-@property (nonatomic) CGFloat arrowAlpha;
-
 // only declare methods here to shut the compiler up if we can't rearrange
 - (FVIcon *)iconAtIndex:(NSUInteger)anIndex;
 - (FVIcon *)_cachedIconForURL:(NSURL *)aURL;
@@ -260,7 +258,6 @@
 @synthesize dataSource;
 @synthesize delegate;
 @dynamic numberOfIcons;
-@synthesize arrowAlpha=_arrowAlpha;
 
 + (void)initialize 
 {
@@ -390,19 +387,14 @@
     [_subtitleCell setLineBreakMode:NSLineBreakByTruncatingTail];
     [_subtitleCell setAlignment:NSTextAlignmentCenter];
     
-    _leftArrow = [[FVArrowButtonCell alloc] 
initWithArrowDirection:FVArrowLeft];
+    _leftArrow = [[FVArrowButton alloc] initWithArrowDirection:FVArrowLeft];
     [_leftArrow setTarget:self];
     [_leftArrow setAction:@selector(leftArrowAction:)];
     
-    _rightArrow = [[FVArrowButtonCell alloc] 
initWithArrowDirection:FVArrowRight];
+    _rightArrow = [[FVArrowButton alloc] initWithArrowDirection:FVArrowRight];
     [_rightArrow setTarget:self];
     [_rightArrow setAction:@selector(rightArrowAction:)];
     
-    _leftArrowFrame = NSZeroRect;
-    _rightArrowFrame = NSZeroRect;
-    _arrowAlpha = 0.0;
-    _fvFlags.hasArrows = NO;
-    
     _minScale = 0.5;
     _maxScale = 16.0;
     
@@ -2603,13 +2595,6 @@
     
     if (isDrawingToScreen) {
         
-        if (_fvFlags.hasArrows || _arrowAlpha > 0.0) {
-            if (NSIntersectsRect(rect, _leftArrowFrame))
-                [(FVArrowButtonCell *)_leftArrow drawWithFrame:_leftArrowFrame 
inView:self alpha:_arrowAlpha];
-            if (NSIntersectsRect(rect, _rightArrowFrame))
-                [(FVArrowButtonCell *)_rightArrow 
drawWithFrame:_rightArrowFrame inView:self alpha:_arrowAlpha];
-        }
-        
         // drop highlight and rubber band are mutually exclusive
         if (_dropIndex != NSNotFound || _fvFlags.dropOperation == FVDropOn) {
             [self _drawDropHighlight];
@@ -3036,7 +3021,7 @@
     [self _updateButtonsForIcon:anIcon];
     NSUInteger r, c;
     // _getGridRow should always succeed; either arrow frame would work here, 
since both are in the same icon
-    if ([self _getGridRow:&r column:&c atPoint:_leftArrowFrame.origin]) {
+    if ([self _getGridRow:&r column:&c atPoint:[_leftArrow frame].origin]) {
         NSSize size = [self 
respondsToSelector:@selector(convertSizeToBacking:)] ? [self 
convertSizeToBacking:_iconSize] : _iconSize;
         // render immediately so the placeholder path doesn't draw
         if ([anIcon needsRenderForSize:size])
@@ -3047,7 +3032,7 @@
 
 - (void)leftArrowAction:(id)sender
 {
-    FVIcon *anIcon = [_leftArrow representedObject];
+    FVIcon *anIcon = [[_leftArrow cell] representedObject];
     [anIcon showPreviousPage];
     [self _redisplayIconAfterPageChanged:anIcon];
 }
@@ -3054,16 +3039,11 @@
 
 - (void)rightArrowAction:(id)sender
 {
-    FVIcon *anIcon = [_rightArrow representedObject];
+    FVIcon *anIcon = [[_rightArrow cell] representedObject];
     [anIcon showNextPage];
     [self _redisplayIconAfterPageChanged:anIcon];
 }
 
-- (void)setArrowAlpha:(CGFloat)arrowAlpha {
-    _arrowAlpha = arrowAlpha;
-    [self setNeedsDisplayInRect:NSUnionRect(_leftArrowFrame, 
_rightArrowFrame)];
-}
-
 - (void)_showArrowsForIconAtIndex:(NSUInteger)anIndex
 {
     NSUInteger r, c;
@@ -3077,11 +3057,11 @@
         
         if ([anIcon pageCount] > 1) {
             
-            if (_arrowAlpha > 0.0) {
-                if (anIcon != [_leftArrow representedObject])
-                    _arrowAlpha = 0.0;
-                // make sure we redraw whatever area previously had the arrows
-                [self setNeedsDisplayInRect:NSUnionRect(_leftArrowFrame, 
_rightArrowFrame)];
+            if ([_leftArrow arrowAlpha] > 0.0) {
+                if (anIcon != [[_leftArrow cell] representedObject]) {
+                    [_leftArrow setArrowAlpha:0.0];
+                    [_rightArrow setArrowAlpha:0.0];
+                }
             }
         
             NSRect iconRect = [self _rectOfIconInRow:r column:c];
@@ -3092,22 +3072,26 @@
             side = fmax(fmin(side, 32.0), 10.0);
             sep = fmin(0.5 * side - 4.0, 4.0);
             // 2 pixels between arrows horizontally, and 4 pixels between 
bottom of arrow and bottom of iconRect
-            _leftArrowFrame = _rightArrowFrame = 
NSMakeRect(ceil(NSMidX(iconRect) + 0.5 * sep), NSMaxY(iconRect) - side - sep, 
side, side);
-            _leftArrowFrame.origin.x -= side + sep;
+            NSRect arrowFrame = NSMakeRect(ceil(NSMidX(iconRect) + 0.5 * sep), 
NSMaxY(iconRect) - side - sep, side, side);
+            [_rightArrow setFrame:arrowFrame];
+            arrowFrame.origin.x -= side + sep;
+            [_leftArrow setFrame:arrowFrame];
             
-            [_leftArrow setRepresentedObject:anIcon];
-            [_rightArrow setRepresentedObject:anIcon];
-            _fvFlags.hasArrows = YES;
-
+            [[_leftArrow cell] setRepresentedObject:anIcon];
+            [[_rightArrow cell] setRepresentedObject:anIcon];
+            
             // set enabled states
             [self _updateButtonsForIcon:anIcon];  
-            [self _setNeedsDisplayForIconInRow:r column:c];
             
-            if (_arrowAlpha < 1.0) {
+            [self addSubview:_leftArrow];
+            [self addSubview:_rightArrow];
+            
+            if ([_leftArrow arrowAlpha] < 1.0) {
                 [NSAnimationContext runAnimationGroup:^(NSAnimationContext 
*context){
                     [context setTimingFunction:[CAMediaTimingFunction 
functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
                     [context setDuration:0.3];
-                    [[self animator] setArrowAlpha:1.0];
+                    [[_leftArrow animator] setArrowAlpha:1.0];
+                    [[_rightArrow animator] setArrowAlpha:1.0];
                 } completionHandler:^{}];
             }
         }
@@ -3116,15 +3100,20 @@
 
 - (void)_hideArrows
 {
-    if (_fvFlags.hasArrows) {
-        _fvFlags.hasArrows = NO;
-        [_leftArrow setRepresentedObject:nil];
-        [_rightArrow setRepresentedObject:nil];
+    if ([[_leftArrow cell] representedObject]) {
+        [[_leftArrow cell] setRepresentedObject:nil];
+        [[_rightArrow cell] setRepresentedObject:nil];
         [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
             [context setTimingFunction:[CAMediaTimingFunction 
functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
             [context setDuration:0.3];
-            [[self animator] setArrowAlpha:0.0];
-        } completionHandler:^{}];
+            [[_leftArrow animator] setArrowAlpha:0.0];
+            [[_rightArrow animator] setArrowAlpha:0.0];
+        } completionHandler:^{
+            if ([[_leftArrow cell] representedObject] == nil) {
+                [_leftArrow removeFromSuperview];
+                [_rightArrow removeFromSuperview];
+            }
+        }];
     }
 }
 
@@ -3256,14 +3245,8 @@
     NSUInteger flags = [event modifierFlags];
     NSUInteger r, c, i;
     
-    if (_fvFlags.hasArrows && NSMouseInRect(p, _leftArrowFrame, [self 
isFlipped])) {
-        [_leftArrow trackMouse:event inRect:_leftArrowFrame ofView:self 
untilMouseUp:YES];
-    }
-    else if (_fvFlags.hasArrows && NSMouseInRect(p, _rightArrowFrame, [self 
isFlipped])) {
-        [_rightArrow trackMouse:event inRect:_rightArrowFrame ofView:self 
untilMouseUp:YES];
-    }
     // mark this icon for highlight if necessary
-    else if ([self _getGridRow:&r column:&c atPoint:p]) {
+    if ([self _getGridRow:&r column:&c atPoint:p]) {
         
         // remember _indexForGridRow:column: returns NSNotFound if you're in 
an empty slot of an existing row/column, but that's a deselect event so we 
still need to remove all selection indexes and mark for redisplay
         i = [self _indexForGridRow:r column:c];

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



_______________________________________________
Bibdesk-commit mailing list
Bibdesk-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit

Reply via email to