Revision: 29171
http://sourceforge.net/p/bibdesk/svn/29171
Author: hofman
Date: 2025-04-23 09:34:04 +0000 (Wed, 23 Apr 2025)
Log Message:
-----------
Always use a separate view to draw the selection highlights. Needed to make the
possible visual effect view invisible for mouse events.
Modified Paths:
--------------
trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.h
trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m
Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.h
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.h 2025-04-22
15:49:17 UTC (rev 29170)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.h 2025-04-23
09:34:04 UTC (rev 29171)
@@ -194,7 +194,7 @@
@end
-@class FVSliderWindow, FVOperationQueue, FVBackgroundView, FVArrowButton,
FVDropHighlightView;
+@class FVSliderWindow, FVOperationQueue, FVBackgroundView, FVHighlightView,
FVArrowButton, FVDropHighlightView;
/**
FVFileView is the primary class in the framework.
@@ -223,7 +223,7 @@
NSUInteger _lastClickedIndex;
NSView *_contentView;
NSView *_rubberBandView;
- NSView *_highlightView;
+ FVHighlightView *_highlightView;
FVDropHighlightView *_dropHighlightView;
struct __fvFlags {
unsigned int displayMode:2;
Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m 2025-04-22
15:49:17 UTC (rev 29170)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m 2025-04-23
09:34:04 UTC (rev 29171)
@@ -109,6 +109,12 @@
#define NSEventModifierFlagOption NSAlternateKeyMask
#endif
+typedef NS_ENUM(NSUInteger, FVHighlightStyle) {
+ FVHighlightStyleBordered,
+ FVHighlightStyleUnbordered,
+ FVHighlightStyleTranslucent
+};
+
@interface _FVURLInfo : NSObject
{
@public;
@@ -147,6 +153,17 @@
#pragma mark -
+@interface FVHighlightView : NSView {
+ NSArray *_highlightRects;
+ FVHighlightStyle _highlightStyle;
+ CGLayerRef _layer;
+}
+@property (nonatomic, copy) NSArray *highlightRects;
+@property (nonatomic) FVHighlightStyle highlightStyle;
+@end
+
+#pragma mark -
+
@interface FVRubberBandView : NSView
@end
@@ -244,6 +261,8 @@
@property (nonatomic, copy) NSArray *iconURLs;
+@property (nonatomic, readonly) FVHighlightStyle highlightStyle;
+
// only declare methods here to shut the compiler up if we can't rearrange
- (FVIcon *)iconAtIndex:(NSUInteger)anIndex;
- (FVIcon *)_cachedIconForURL:(NSURL *)aURL;
@@ -268,8 +287,8 @@
- (void)handlePreviewerWillClose:(NSNotification *)aNote;
- (void)_registerForKeyOrMainStateNotifications;
- (void)_unregisterForKeyOrMainStateNotifications;
-- (void)_addHighlightView;
-- (void)_updateHighlightViewMask;
+- (void)_updateHighlightRects;
+- (void)_updateHighlightStyle;
@end
@@ -342,6 +361,11 @@
+ (BOOL)accessInstanceVariablesDirectly { return NO; }
- (void)_commonInit {
+ _highlightView = [[FVHighlightView alloc] initWithFrame:[self bounds]];
+ [_highlightView setHighlightStyle:floor(NSAppKitVersionNumber) >
NSAppKitVersionNumber10_9 ? FVHighlightStyleUnbordered :
FVHighlightStyleBordered];
+ [_highlightView setAutoresizingMask:NSViewWidthSizable |
NSViewHeightSizable];
+ [self addSubview:_highlightView];
+
_contentView = [[FVDisplayView alloc] initWithFrame:[self bounds]
delegate:self];
[_contentView setAutoresizingMask:NSViewWidthSizable |
NSViewHeightSizable];
[self addSubview:_contentView];
@@ -497,16 +521,6 @@
#pragma mark API
-static inline BOOL _allowsUnborderedHighlight(NSColor *color) {
- if (color == nil)
- return YES;
- if ([[color colorSpaceName] isEqualToString:NSNamedColorSpace] == NO ||
[[color catalogNameComponent] isEqualToString:@"System"] == NO)
- return NO;
- if ([[color colorNameComponent] hasSuffix:@"BackgroundColor"] || [[color
colorNameComponent] hasSuffix:@"RowColor"])
- return floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_15 ||
[[color colorNameComponent] isEqualToString:@"underPageBackgroundColor"] == NO;
- return NO;
-}
-
- (void)setBackgroundColor:(NSColor *)aColor;
{
if (_backgroundColor != aColor) {
@@ -518,19 +532,7 @@
}
_backgroundColor = [aColor copy];
[_backgroundView setBackgroundColor:_backgroundColor];
- if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_9) {
- _fvFlags.unborderedHighlight =
_allowsUnborderedHighlight(_backgroundColor);
- CGLayerRelease(_selectionOverlay);
- _selectionOverlay = NULL;
- if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_15) {
- if (_backgroundColor == nil && _backgroundView) {
- [self _addHighlightView];
- } else if (_highlightView) {
- [_highlightView removeFromSuperview];
- _highlightView = nil;
- }
- }
- }
+ [self _updateHighlightStyle];
}
}
@@ -850,10 +852,7 @@
if (indexSet != _selectionIndexes) {
_selectionIndexes = [[NSIndexSet alloc] initWithIndexSet:indexSet];
- if (_highlightView)
- [self _updateHighlightViewMask];
- else
- [self setNeedsDisplay:YES];
+ [self _updateHighlightRects];
NSAccessibilityPostNotification(NSAccessibilityUnignoredAncestor(self),
NSAccessibilityFocusedUIElementChangedNotification);
@@ -1114,10 +1113,7 @@
if (_backgroundView) {
[_backgroundView removeFromSuperview];
_backgroundView = nil;
- if (_highlightView) {
- [_highlightView removeFromSuperview];
- _highlightView = nil;
- }
+ [self _updateHighlightStyle];
}
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSViewFrameDidChangeNotification object:nil];
@@ -1143,15 +1139,8 @@
[_backgroundView setBackgroundColor:_backgroundColor];
[scrollView addSubview:_backgroundView
positioned:NSWindowBelow relativeTo:nil];
[scrollView setDrawsBackground:NO];
- if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_15)
{
- if (_backgroundColor == nil) {
- [self _addHighlightView];
- } else if (_highlightView) {
- [_highlightView removeFromSuperview];
- _highlightView = nil;
- }
- }
}
+ [self _updateHighlightStyle];
}
}
}
@@ -1493,7 +1482,7 @@
}
}
- [self _updateHighlightViewMask];
+ [self _updateHighlightRects];
}
}
@@ -2034,40 +2023,47 @@
}
}
-#pragma mark Highlight view layout
+#pragma mark Highlight view updates
-- (void)_updateHighlightViewMask {
- if (_highlightView) {
- NSImage *image = nil;
- NSRect bounds = [self bounds];
- if (NSIsEmptyRect(bounds) == NO) {
- image = [[NSImage alloc] initWithSize:bounds.size];
- if ([_selectionIndexes count]) {
- [image lockFocusFlipped:YES];
- [[NSColor blackColor] setFill];
- [_selectionIndexes enumerateIndexesUsingBlock:^(NSUInteger i,
BOOL *stop){
- NSRect highlightRect = [self _rectOfIconAtIndex:i];
- if (NSIsEmptyRect(highlightRect) == NO) {
- highlightRect = NSInsetRect(highlightRect,
HIGHLIGHT_INSET, HIGHLIGHT_INSET);
- [[NSBezierPath bezierPathWithRoundedRect:highlightRect
xRadius:6.0 yRadius:6.0] fill];
- }
- }];
- [image unlockFocus];
+- (void)_updateHighlightRects {
+ NSMutableArray *highlightRects = nil;
+
+ if ([_selectionIndexes count]) {
+ highlightRects = [NSMutableArray array];
+ [_selectionIndexes enumerateIndexesUsingBlock:^(NSUInteger i, BOOL
*stop){
+ NSRect highlightRect = [self _rectOfIconAtIndex:i];
+ if (NSIsEmptyRect(highlightRect) == NO) {
+ highlightRect = NSInsetRect(highlightRect, HIGHLIGHT_INSET,
HIGHLIGHT_INSET);
+ [highlightRects addObject:[NSValue
valueWithRect:highlightRect]];
}
- [image setTemplate:YES];
- }
- [_highlightView setValue:image forKey:@"maskImage"];
+ }];
}
+
+ [_highlightView setHighlightRects:highlightRects];
}
-- (void)_addHighlightView {
- if (_highlightView == nil) {
- _highlightView = [[NSClassFromString(@"NSVisualEffectView") alloc]
initWithFrame:[self bounds]];
- [_highlightView setValue:[NSNumber numberWithInteger:4]
forKey:@"material"];
- [_highlightView setAutoresizingMask:NSViewWidthSizable |
NSViewHeightSizable];
- [self _updateHighlightViewMask];
- [self addSubview:_highlightView positioned:NSWindowBelow
relativeTo:nil];
+- (void)_updateHighlightStyle {
+ // for generic colors we want a border so always either the fill or the
stroke contrasts
+ FVHighlightStyle highlightStyle = FVHighlightStyleBordered;
+
+ if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_9) {
+ if (_backgroundColor == nil) {
+ // with a sidebar visual effect background we want a selection
visual effect highlight
+ if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_15 &&
_backgroundView)
+ highlightStyle = FVHighlightStyleTranslucent;
+ else
+ highlightStyle = FVHighlightStyleUnbordered;
+ } else if ([[_backgroundColor colorSpaceName]
isEqualToString:NSNamedColorSpace] && [[_backgroundColor catalogNameComponent]
isEqualToString:@"System"]) {
+ // for system background colors we can use a highlight without
border
+ // except on 10.5- underPageBackgroundColor is very dark (or light
in dark mode)
+ NSString *colorName = [_backgroundColor colorNameComponent];
+ if (([colorName hasSuffix:@"BackgroundColor"] || [colorName
hasSuffix:@"RowColor"]) &&
+ (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_15 ||
[colorName isEqualToString:@"underPageBackgroundColor"] == NO))
+ highlightStyle = FVHighlightStyleUnbordered;
+ }
}
+
+ [_highlightView setHighlightStyle:highlightStyle];
}
#pragma mark Cache thread
@@ -2237,52 +2233,6 @@
}
}
-- (void)_drawHighlightInRect:(NSRect)aRect
inContext:(CGContextRef)drawingContext;
-{
- // drawing into a CGImage and then overlaying it keeps the rubber band
highlight much more responsive
- if (NULL == _selectionOverlay) {
-
- _selectionOverlay = CGLayerCreateWithContext(drawingContext,
CGSizeMake(NSWidth(aRect), NSHeight(aRect)), NULL);
- CGContextRef layerContext = CGLayerGetContext(_selectionOverlay);
- NSRect imageRect = NSZeroRect;
- CGSize layerSize = CGLayerGetSize(_selectionOverlay);
- imageRect.size.height = layerSize.height;
- imageRect.size.width = layerSize.width;
- CGContextClearRect(layerContext, NSRectToCGRect(imageRect));
-
- NSGraphicsContext *nsContext = [NSGraphicsContext
graphicsContextWithGraphicsPort:layerContext flipped:YES];
- [NSGraphicsContext saveGraphicsState];
- [NSGraphicsContext setCurrentContext:nsContext];
- [nsContext saveGraphicsState];
-
- // @@ Dark mode
- if (_fvFlags.unborderedHighlight) {
- // [NSAppearance currentAppearance] should alwaye be [self
effectiveAppearance] here
- NSColor *fillColor = [[NSColor textColor]
colorWithAlphaComponent:32.0 / 255.0];
- NSBezierPath *p = [NSBezierPath
bezierPathWithRoundedRect:imageRect xRadius:6.0 yRadius:6.0];
- [fillColor setFill];
- [p fill];
- } else {
- NSColor *strokeColor = [NSColor colorWithCalibratedWhite:224.0 /
255.0 alpha:124.0 / 255.0];
- NSColor *fillColor = [NSColor colorWithCalibratedWhite:0.0
alpha:32.0 / 255.0];
- [strokeColor setStroke];
- [fillColor setFill];
- imageRect = NSInsetRect(imageRect, 1.0, 1.0);
- NSBezierPath *p = [NSBezierPath
bezierPathWithRoundedRect:imageRect xRadius:5.0 yRadius:5.0];
- [p setLineWidth:2.0];
- [p stroke];
- imageRect = NSInsetRect(imageRect, 1.0, 1.0);
- p = [NSBezierPath bezierPathWithRoundedRect:imageRect xRadius:4.0
yRadius:4.0];
- [p fill];
- [p setLineWidth:1.0];
- }
-
- [NSGraphicsContext restoreGraphicsState];
- }
-
- CGContextDrawLayerInRect(drawingContext, NSRectToCGRect(aRect),
_selectionOverlay);
-}
-
#define DROP_MESSAGE_MIN_FONTSIZE ((CGFloat) 8.0)
#define DROP_MESSAGE_MAX_INSET ((CGFloat) 20.0)
@@ -2705,24 +2655,6 @@
FVFillBackgroundColorOrGradient(_backgroundColor, rect, [self
visibleRect], [self window]);
}
- if ([_selectionIndexes count] > 0 && _highlightView == nil) {
- CGContextRef context = [[NSGraphicsContext currentContext]
graphicsPort];
-
- CGContextSaveGState(context);
- CGContextSetBlendMode(context, kCGBlendModeNormal);
-
- [_selectionIndexes enumerateIndexesUsingBlock:^(NSUInteger i, BOOL
*stop){
- NSRect highlightRect = [self _rectOfIconAtIndex:i];
- if (NSIsEmptyRect(highlightRect) == NO) {
- highlightRect = NSInsetRect(highlightRect, HIGHLIGHT_INSET,
HIGHLIGHT_INSET);
- if ([self needsToDrawRect:highlightRect])
- [self _drawHighlightInRect:highlightRect
inContext:context];
- }
- }];
-
- CGContextRestoreGState(context);
- }
-
#if DEBUG_GRID
[[NSColor grayColor] set];
NSRect r = NSInsetRect([self bounds], [self _leftMargin], [self
_topMargin]);
@@ -5191,6 +5123,150 @@
}
}
+#pragma mark -
+
+@implementation FVHighlightView
+
+@synthesize highlightRects=_highlightRects;
+@synthesize highlightStyle=_highlightStyle;
+
+- (BOOL)isFlipped { return YES; }
+
+- (NSView *)hitTest:(NSPoint)point { return nil; }
+
+- (void)viewDidChangeEffectiveAppearance {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpartial-availability"
+ [super viewDidChangeEffectiveAppearance];
+#pragma clang diagnostic pop
+ CGLayerRelease(_layer);
+ _layer = NULL;
+}
+
+- (void)_updateMaskImage {
+ if ([[self subviews] count]) {
+ NSImage *image = nil;
+ NSRect bounds = [self bounds];
+ if (NSIsEmptyRect(bounds) == NO) {
+ image = [[NSImage alloc] initWithSize:bounds.size];
+ if ([_highlightRects count]) {
+ [image lockFocusFlipped:YES];
+ [[NSColor blackColor] setFill];
+ for (NSValue *value in _highlightRects) {
+ NSRect highlightRect = [value rectValue];
+ [[NSBezierPath bezierPathWithRoundedRect:highlightRect
xRadius:6.0 yRadius:6.0] fill];
+ }
+ [image unlockFocus];
+ }
+ [image setTemplate:YES];
+ }
+ [[[self subviews] objectAtIndex:0] setValue:image forKey:@"maskImage"];
+ }
+}
+
+- (void)setHighlightRects:(NSArray *)array
+{
+ if (array != _highlightRects) {
+ _highlightRects = [array copy];
+ if (_highlightStyle == FVHighlightStyleTranslucent)
+ [self _updateMaskImage];
+ else
+ [self setNeedsDisplay:YES];
+ }
+}
+
+- (void)setHighlightStyle:(FVHighlightStyle)style
+{
+ if (style != _highlightStyle) {
+ _highlightStyle = style;
+
+ CGLayerRelease(_layer);
+ _layer = NULL;
+
+ if (_highlightStyle == FVHighlightStyleTranslucent) {
+ if ([[self subviews] count] == 0) {
+ NSView *view = [[NSClassFromString(@"NSVisualEffectView")
alloc] initWithFrame:[self bounds]];
+ [view setValue:[NSNumber numberWithInteger:4]
forKey:@"material"];
+ [view setAutoresizingMask:NSViewWidthSizable |
NSViewHeightSizable];
+ [self addSubview:view];
+ [self _updateMaskImage];
+ }
+ } else if ([[self subviews] count]) {
+ [[[self subviews] objectAtIndex:0] removeFromSuperview];
+ }
+ }
+}
+
+- (void)_drawHighlightInRect:(NSRect)aRect
inContext:(CGContextRef)drawingContext;
+{
+ if (NULL == _layer) {
+
+ _layer = CGLayerCreateWithContext(drawingContext,
CGSizeMake(NSWidth(aRect), NSHeight(aRect)), NULL);
+ CGContextRef layerContext = CGLayerGetContext(_layer);
+ NSRect imageRect = NSZeroRect;
+ CGSize layerSize = CGLayerGetSize(_layer);
+ imageRect.size.height = layerSize.height;
+ imageRect.size.width = layerSize.width;
+ CGContextClearRect(layerContext, NSRectToCGRect(imageRect));
+
+ NSGraphicsContext *nsContext = [NSGraphicsContext
graphicsContextWithGraphicsPort:layerContext flipped:YES];
+ [NSGraphicsContext saveGraphicsState];
+ [NSGraphicsContext setCurrentContext:nsContext];
+ [nsContext saveGraphicsState];
+
+ // @@ Dark mode
+ if (_highlightStyle == FVHighlightStyleUnbordered) {
+ // [NSAppearance currentAppearance] should alwaye be [self
effectiveAppearance] here
+ NSColor *fillColor = [[NSColor textColor]
colorWithAlphaComponent:32.0 / 255.0];
+ NSBezierPath *p = [NSBezierPath
bezierPathWithRoundedRect:imageRect xRadius:6.0 yRadius:6.0];
+ [fillColor setFill];
+ [p fill];
+ } else if (_highlightStyle == FVHighlightStyleBordered) {
+ NSColor *strokeColor = [NSColor colorWithCalibratedWhite:224.0 /
255.0 alpha:124.0 / 255.0];
+ NSColor *fillColor = [NSColor colorWithCalibratedWhite:0.0
alpha:32.0 / 255.0];
+ [strokeColor setStroke];
+ [fillColor setFill];
+ imageRect = NSInsetRect(imageRect, 1.0, 1.0);
+ NSBezierPath *p = [NSBezierPath
bezierPathWithRoundedRect:imageRect xRadius:5.0 yRadius:5.0];
+ [p setLineWidth:2.0];
+ [p stroke];
+ imageRect = NSInsetRect(imageRect, 1.0, 1.0);
+ p = [NSBezierPath bezierPathWithRoundedRect:imageRect xRadius:4.0
yRadius:4.0];
+ [p fill];
+ [p setLineWidth:1.0];
+ }
+
+ [NSGraphicsContext restoreGraphicsState];
+ }
+
+ CGContextDrawLayerInRect(drawingContext, NSRectToCGRect(aRect), _layer);
+}
+
+- (void)drawRect:(NSRect)dirtyRect
+{
+ if ([_highlightRects count] && _highlightStyle !=
FVHighlightStyleTranslucent) {
+ if (_layer && NSEqualSizes(NSSizeFromCGSize(CGLayerGetSize(_layer)),
[[_highlightRects objectAtIndex:0] rectValue].size) == NO) {
+ CGLayerRelease(_layer);
+ _layer = NULL;
+ }
+
+ CGContextRef context = [[NSGraphicsContext currentContext]
graphicsPort];
+
+ CGContextSaveGState(context);
+ CGContextSetBlendMode(context, kCGBlendModeNormal);
+
+ for (NSValue *value in _highlightRects) {
+ NSRect highlightRect = [value rectValue];
+ if ([self needsToDrawRect:highlightRect])
+ [self _drawHighlightInRect:highlightRect inContext:context];
+ }
+
+ CGContextRestoreGState(context);
+ }
+}
+
+@end
+
#pragma mark
@implementation FVRubberBandView
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