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
[email protected]
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit