Skip to content

Commit a20e416

Browse files
committed
Use lighter scrollbar scolor when background is dark.
1 parent ebc2c46 commit a20e416

8 files changed

+193
-4
lines changed

Headers/iTerm/PTYScrollView.h

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
{
3434
BOOL userScroll;
3535
}
36+
37+
@property (nonatomic, assign) BOOL hasDarkBackground;
38+
3639
+ (BOOL)isCompatibleWithOverlayScrollers;
3740
- (id)init;
3841
- (void) mouseDown: (NSEvent *)theEvent;

Headers/iTerm/PTYTextView.h

+1
Original file line numberDiff line numberDiff line change
@@ -559,5 +559,6 @@ typedef enum {
559559
// Returns true if any onscreen char is blinking.
560560
- (BOOL)_markChangedSelectionAndBlinkDirty:(BOOL)redrawBlink width:(int)width;
561561

562+
- (double)_perceivedBrightness:(NSColor*)c;
562563
@end
563564

NSBitmapImageRep+CoreImage.h

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// From http://www.cocoadev.com/index.pl?NSImageCategory
2+
//
3+
// NSBitmapImageRep+CoreImage.h
4+
// iTerm2
5+
//
6+
7+
#import <Foundation/Foundation.h>
8+
#import <Cocoa/Cocoa.h>
9+
10+
@interface NSBitmapImageRep (CoreImage)
11+
/* Draws the specified image representation using Core Image. */
12+
- (void)drawAtPoint:(NSPoint)point
13+
fromRect:(NSRect)fromRect
14+
coreImageFilter:(NSString *)filterName
15+
arguments:(NSDictionary *)arguments;
16+
@end

NSBitmapImageRep+CoreImage.m

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// From http://www.cocoadev.com/index.pl?NSImageCategory
2+
// NSBitmapImageRep+CoreImage.m
3+
// iTerm2
4+
5+
#import <QuartzCore/QuartzCore.h>
6+
#import "NSBitmapImageRep+CoreImage.h"
7+
#import "NSImage+CoreImage.h"
8+
9+
#define CIIMAGE_PADDING 16.0f
10+
11+
@implementation NSBitmapImageRep (CoreImage)
12+
13+
- (void)drawAtPoint: (NSPoint)point fromRect: (NSRect)fromRect coreImageFilter: (NSString *)filterName arguments: (NSDictionary *)arguments {
14+
NSAutoreleasePool *pool;
15+
CIFilter *filter;
16+
CIImage *before;
17+
CIImage *after;
18+
CIContext *ciContext;
19+
CGContextRef cgContext;
20+
21+
pool = [[NSAutoreleasePool alloc] init];
22+
before = nil;
23+
24+
@try {
25+
before = [[CIImage alloc] initWithBitmapImageRep: self];
26+
if (before) {
27+
filter = [CIFilter filterWithName: filterName];
28+
[filter setDefaults];
29+
if (arguments)
30+
[filter setValuesForKeysWithDictionary: arguments];
31+
[filter setValue: before forKey: @"inputImage"];
32+
} else {
33+
filter = nil;
34+
}
35+
36+
after = [filter valueForKey: @"outputImage"];
37+
if (after) {
38+
if (![[arguments objectForKey: @"gt_noRenderPadding"] boolValue]) {
39+
/* Add a wide berth to the bounds -- the padding can be turned
40+
off by passing an NSNumber with a YES value in the argument
41+
"gt_noRenderPadding" in the argument dictionary. */
42+
fromRect.origin.x -= CIIMAGE_PADDING;
43+
fromRect.origin.y -= CIIMAGE_PADDING;
44+
fromRect.size.width += CIIMAGE_PADDING * 2.0f;
45+
fromRect.size.height += CIIMAGE_PADDING * 2.0f;
46+
point.x -= CIIMAGE_PADDING;
47+
point.y -= CIIMAGE_PADDING;
48+
}
49+
50+
cgContext = CGContextRetain((CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]);
51+
if (cgContext) {
52+
ciContext = [CIContext contextWithCGContext: cgContext options: nil];
53+
[ciContext
54+
drawImage: after
55+
atPoint: *(CGPoint *)(&point)
56+
fromRect: *(CGRect *)(&fromRect)];
57+
CGContextRelease(cgContext);
58+
}
59+
}
60+
} @catch (NSException *e) {
61+
NSLog("exception encountered during core image filtering: %@", e);
62+
} @finally {
63+
[before release];
64+
}
65+
66+
[pool release];
67+
}
68+
@end

NSImage+CoreImage.h

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// From http://www.cocoadev.com/index.pl?NSImageCategory
2+
//
3+
// NSImage+CoreImage.h
4+
// iTerm2
5+
6+
#import <Foundation/Foundation.h>
7+
#import <Cocoa/Cocoa.h>
8+
9+
@interface NSImage (CoreImage)
10+
/* Draws the specified image using Core Image. */
11+
- (void)drawAtPoint: (NSPoint)point fromRect: (NSRect)fromRect coreImageFilter: (NSString *)filterName arguments: (NSDictionary *)arguments;
12+
13+
/* Gets a bitmap representation of the image, or creates one if the image does not have any. */
14+
- (NSBitmapImageRep *)bitmapImageRepresentation;
15+
@end
16+

NSImage+CoreImage.m

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// From http://www.cocoadev.com/index.pl?NSImageCategory
2+
//
3+
// NSImage+CoreImage.m
4+
// iTerm2
5+
6+
#import "NSImage+CoreImage.h"
7+
8+
@implementation NSImage (CoreImage)
9+
- (void)drawAtPoint: (NSPoint)point fromRect: (NSRect)fromRect coreImageFilter: (NSString *)filterName arguments: (NSDictionary *)arguments {
10+
NSAutoreleasePool *pool;
11+
NSBitmapImageRep *rep;
12+
13+
pool = [[NSAutoreleasePool alloc] init];
14+
15+
if (filterName) {
16+
rep = [self bitmapImageRepresentation];
17+
[rep
18+
drawAtPoint: point
19+
fromRect: fromRect
20+
coreImageFilter: filterName
21+
arguments: arguments];
22+
} else {
23+
/* bypass core image if no filter is specified */
24+
[self
25+
drawAtPoint: point
26+
fromRect: fromRect
27+
operation: NSCompositeSourceOver
28+
fraction: 1.0f];
29+
}
30+
31+
[pool release];
32+
}
33+
34+
- (NSBitmapImageRep *)bitmapImageRepresentation {
35+
NSImageRep *rep;
36+
NSEnumerator *e;
37+
Class bitmapImageRep;
38+
39+
bitmapImageRep = [NSBitmapImageRep class];
40+
e = [[self representations] objectEnumerator];
41+
while ((rep = [e nextObject]) != nil) {
42+
if ([rep isKindOfClass: bitmapImageRep])
43+
break;
44+
rep = nil;
45+
}
46+
47+
if (!rep)
48+
rep = [NSBitmapImageRep imageRepWithData: [self TIFFRepresentation]];
49+
50+
return (NSBitmapImageRep *)rep;
51+
}
52+
53+
@end

PTYScrollView.m

+28
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,12 @@
3535
#import <iTerm/PTYScrollView.h>
3636
#import <iTerm/PTYTextView.h>
3737
#import <PreferencePanel.h>
38+
#import <Cocoa/Cocoa.h>
3839

3940
@implementation PTYScroller
4041

42+
@synthesize hasDarkBackground;
43+
4144
- (id)init
4245
{
4346
userScroll=NO;
@@ -97,6 +100,31 @@ - (NSScrollerPart)hitPart
97100
return [super hitPart];
98101
}
99102

103+
- (void)drawRect:(NSRect)dirtyRect {
104+
if (IsLionOrLater() && self.hasDarkBackground) {
105+
NSImage *superDrawn = [[NSImage alloc] initWithSize:NSMakeSize(dirtyRect.origin.x + dirtyRect.size.width,
106+
dirtyRect.origin.y + dirtyRect.size.height)];
107+
[superDrawn lockFocus];
108+
[super drawRect:dirtyRect];
109+
[superDrawn unlockFocus];
110+
111+
NSImage *temp = [[NSImage alloc] initWithSize:[superDrawn size]];
112+
[temp lockFocus];
113+
[superDrawn drawAtPoint:dirtyRect.origin
114+
fromRect:dirtyRect
115+
coreImageFilter:@"CIColorControls"
116+
arguments:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithDouble:0.5], @"inputBrightness", nil]];
117+
[temp unlockFocus];
118+
119+
[temp drawAtPoint:dirtyRect.origin
120+
fromRect:dirtyRect
121+
operation:NSCompositeCopy
122+
fraction:1.0];
123+
} else {
124+
[super drawRect:dirtyRect];
125+
}
126+
}
127+
100128
@end
101129

102130
@implementation PTYScrollView

PTYTextView.m

+8-4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
// Minimum distance that the mouse must move before a cmd+drag will be
6767
// recognized as a drag.
6868
static const int kDragThreshold = 3;
69+
static const double kBackgroundConsideredDarkThreshold = 0.5;
6970

7071
// When drawing lines, we use this structure to represent a run of cells of
7172
// the same font, color, and attributes.
@@ -113,6 +114,10 @@
113114
static NSImage* wrapToTopImage = nil;
114115
static NSImage* wrapToBottomImage = nil;
115116

117+
static CGFloat PerceivedBrightness(CGFloat r, CGFloat g, CGFloat b) {
118+
return (RED_COEFFICIENT * r) + (GREEN_COEFFICIENT * g) + (BLUE_COEFFICIENT * b);
119+
}
120+
116121
@interface Coord : NSObject
117122
{
118123
@public
@@ -425,6 +430,9 @@ - (void)setBGColor:(NSColor*)color
425430
[defaultBGColor release];
426431
[color retain];
427432
defaultBGColor = color;
433+
PTYScroller *scroller = (PTYScroller*)[[[dataSource session] SCROLLVIEW] verticalScroller];
434+
BOOL isDark = ([self _perceivedBrightness:color] < kBackgroundConsideredDarkThreshold);
435+
[scroller setHasDarkBackground:isDark];
428436
[self setNeedsDisplay:YES];
429437
}
430438

@@ -4477,10 +4485,6 @@ - (int)_setGlyphsInRun:(CharRun*)charRunArray
44774485
return newRuns;
44784486
}
44794487

4480-
static CGFloat PerceivedBrightness(CGFloat r, CGFloat g, CGFloat b) {
4481-
return (RED_COEFFICIENT * r) + (GREEN_COEFFICIENT * g) + (BLUE_COEFFICIENT * b);
4482-
}
4483-
44844488
- (double)_perceivedBrightness:(NSColor*) c
44854489
{
44864490
return PerceivedBrightness([c redComponent], [c greenComponent], [c blueComponent]);

0 commit comments

Comments
 (0)