diff options
author | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-31 15:17:11 +0000 |
---|---|---|
committer | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-31 15:17:11 +0000 |
commit | 203aa8f73aad8d63c836da3d00f1ab52c0021d8b (patch) | |
tree | 7a07fa5242f65aaa8522c79259b1e305f2d02de7 /chrome/browser/cocoa/tab_view.mm | |
parent | f6e0b0e9fcf638713d82b8e0cc5b3fcc9d845fef (diff) | |
download | chromium_src-203aa8f73aad8d63c836da3d00f1ab52c0021d8b.zip chromium_src-203aa8f73aad8d63c836da3d00f1ab52c0021d8b.tar.gz chromium_src-203aa8f73aad8d63c836da3d00f1ab52c0021d8b.tar.bz2 |
Updates to clean up default theme and add hover states.
Patch by Cole.
BUG=http://crbug.com/18573;http://crbug.com/18574;http://crbug.com/18360;http://crbug.com/18438
TEST=none
Review URL: http://codereview.chromium.org/165499
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@24881 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa/tab_view.mm')
-rw-r--r-- | chrome/browser/cocoa/tab_view.mm | 189 |
1 files changed, 139 insertions, 50 deletions
diff --git a/chrome/browser/cocoa/tab_view.mm b/chrome/browser/cocoa/tab_view.mm index c5bc791..16074e9 100644 --- a/chrome/browser/cocoa/tab_view.mm +++ b/chrome/browser/cocoa/tab_view.mm @@ -13,9 +13,13 @@ static const CGFloat kInsetMultiplier = 2.0/3.0; static const CGFloat kControlPoint1Multiplier = 1.0/3.0; static const CGFloat kControlPoint2Multiplier = 3.0/8.0; +static const NSTimeInterval kAnimationShowDuration = 0.2; +static const NSTimeInterval kAnimationHideDuration = 0.4; + @implementation TabView @synthesize state = state_; +@synthesize hoverAlpha = hoverAlpha_; - (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; @@ -34,18 +38,18 @@ static const CGFloat kControlPoint2Multiplier = 3.0/8.0; // to the |closeButton_| view, but we'll handle the message ourself. // The mouseover is always enabled, because the close button works // regardless of key/main/active status. - trackingArea_.reset( + closeTrackingArea_.reset( [[NSTrackingArea alloc] initWithRect:[closeButton_ bounds] options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways owner:self userInfo:nil]); - [closeButton_ addTrackingArea:trackingArea_.get()]; + [closeButton_ addTrackingArea:closeTrackingArea_.get()]; } - (void)dealloc { // [self gtm_unregisterForThemeNotifications]; - [closeButton_ removeTrackingArea:trackingArea_.get()]; + [closeButton_ removeTrackingArea:closeTrackingArea_.get()]; [super dealloc]; } @@ -56,16 +60,57 @@ static const CGFloat kControlPoint2Multiplier = 3.0/8.0; return YES; } +- (void)adjustHoverValue { + NSTimeInterval thisUpdate = [NSDate timeIntervalSinceReferenceDate]; + + NSTimeInterval elapsed = thisUpdate - lastHoverUpdate_; + + CGFloat opacity = [self hoverAlpha]; + if (isMouseInside_) { + opacity += elapsed / kAnimationShowDuration; + } else { + opacity -= elapsed / kAnimationHideDuration; + } + + if (!isMouseInside_ && opacity < 0) { + opacity = 0; + } else if (isMouseInside_ && opacity > 1) { + opacity = 1; + } else { + [self performSelector:_cmd withObject:nil afterDelay:0.02]; + } + lastHoverUpdate_ = thisUpdate; + [self setHoverAlpha:opacity]; + + [self setNeedsDisplay:YES]; +} + - (void)mouseEntered:(NSEvent *)theEvent { - // We only set up one tracking area, so we know any mouseEntered: - // messages are for close button mouseovers. - [closeButton_ setImage:nsimage_cache::ImageNamed(@"close_bar_h.pdf")]; + if ([theEvent trackingArea] == closeTrackingArea_) { + [closeButton_ setImage:nsimage_cache::ImageNamed(@"close_bar_h.pdf")]; + } else { + lastHoverUpdate_ = [NSDate timeIntervalSinceReferenceDate]; + isMouseInside_ = YES; + [self adjustHoverValue]; + [self setNeedsDisplay:YES]; + } +} + +- (void)mouseMoved:(NSEvent *)theEvent { + hoverPoint_ = [self convertPoint:[theEvent locationInWindow] + fromView:nil]; + [self setNeedsDisplay:YES]; } - (void)mouseExited:(NSEvent *)theEvent { - // We only set up one tracking area, so we know any mouseExited: - // messages are for close button mouseovers. - [closeButton_ setImage:nsimage_cache::ImageNamed(@"close_bar.pdf")]; + if ([theEvent trackingArea] == closeTrackingArea_) { + [closeButton_ setImage:nsimage_cache::ImageNamed(@"close_bar.pdf")]; + } else { + lastHoverUpdate_ = [NSDate timeIntervalSinceReferenceDate]; + isMouseInside_ = NO; + [self adjustHoverValue]; + [self setNeedsDisplay:YES]; + } } // Determines which view a click in our frame actually hit. It's either this @@ -231,7 +276,6 @@ static const double kDragStartDistance = 3.0; NSRect windowFrame = [[target window] frame]; if (NSPointInRect(thisPoint, windowFrame)) { NSRect tabStripFrame = [[target tabStripView] frame]; - tabStripFrame = [[target tabStripView] convertRectToBase:tabStripFrame]; tabStripFrame.origin = [[target window] convertBaseToScreen:tabStripFrame.origin]; if (NSPointInRect(thisPoint, tabStripFrame)) { @@ -426,11 +470,11 @@ static const double kDragStartDistance = 3.0; // Inset by 0.5 in order to draw on pixels rather than on borders (which would // cause blurry pixels). Decrease height by 1 in order to move away from the // edge for the dark shadow. - rect = NSInsetRect(rect, 0.5, -0.5); + rect = NSInsetRect(rect, -0.5, -0.5); rect.origin.y -= 1; - NSPoint bottomLeft = NSMakePoint(NSMinX(rect), NSMinY(rect)); - NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect)); + NSPoint bottomLeft = NSMakePoint(NSMinX(rect), NSMinY(rect) + 2); + NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect) + 2); NSPoint topRight = NSMakePoint(NSMaxX(rect) - kInsetMultiplier * NSHeight(rect), NSMaxY(rect)); @@ -444,7 +488,7 @@ static const double kDragStartDistance = 3.0; // Outset many of these values by 1 to cause the fill to bleed outside the // clip area. NSBezierPath *path = [NSBezierPath bezierPath]; - [path moveToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y + 1)]; + [path moveToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y - 2)]; [path lineToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y)]; [path lineToPoint:bottomLeft]; [path curveToPoint:topLeft @@ -459,30 +503,7 @@ static const double kDragStartDistance = 3.0; controlPoint2:NSMakePoint(bottomRight.x - baseControlPointOutset, bottomRight.y)]; [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y)]; - [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y + 1)]; - - if (selected) { - // Stroke with a translucent black. - [[NSColor colorWithCalibratedWhite:0.0 alpha:active ? 0.5 : 0.3] set]; - [[NSGraphicsContext currentContext] saveGraphicsState]; - scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]); - [shadow setShadowOffset:NSMakeSize(2, -1)]; - [shadow setShadowBlurRadius:2.0]; - [path fill]; - [[NSGraphicsContext currentContext] restoreGraphicsState]; - } else { - // Stroke with a translucent black. - [[NSBezierPath bezierPathWithRect:NSOffsetRect([self bounds], 0, 1)] - addClip]; - - [[NSColor colorWithCalibratedWhite:0.0 alpha:active ? 0.3 : 0.1] set]; - } - - [[NSGraphicsContext currentContext] saveGraphicsState]; - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.2] set]; - [path setLineWidth:selected ? 2.0 : 1.0]; - [path stroke]; - [[NSGraphicsContext currentContext] restoreGraphicsState]; + [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y - 2)]; GTMTheme *theme = [self gtm_theme]; @@ -491,34 +512,102 @@ static const double kDragStartDistance = 3.0; [theme backgroundPatternColorForStyle:GTMThemeStyleWindow state:GTMThemeStateActiveWindow]; if (windowColor) { - NSPoint phase = [self patternPhase]; [windowColor set]; + + [[NSGraphicsContext currentContext] setPatternPhase:[self patternPhase]]; + } else { + NSPoint phase = [self patternPhase]; + phase.y += 1; [[NSGraphicsContext currentContext] setPatternPhase:phase]; + [[NSColor windowBackgroundColor] set]; + } + + [path fill]; + + NSColor *tabColor = + [theme backgroundPatternColorForStyle:GTMThemeStyleTabBarDeselected + state:GTMThemeStateActiveWindow]; + if (tabColor) { + [tabColor set]; + [[NSGraphicsContext currentContext] setPatternPhase:[self patternPhase]]; } else { - [[NSColor colorWithCalibratedWhite:0.6 alpha:1.0] set]; + [[NSColor colorWithCalibratedWhite:1.0 alpha:0.3] set]; } [path fill]; + } - // Draw the background. [[NSGraphicsContext currentContext] saveGraphicsState]; - CGContextRef context = - (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]); - CGContextBeginTransparencyLayer(context, 0); - if (!selected) - CGContextSetAlpha(context, 0.5); [path addClip]; - [super drawRect:rect]; - CGContextEndTransparencyLayer(context); + if (selected || hoverAlpha_ > 0) { + // Draw the background. + CGFloat backgroundAlpha = hoverAlpha_ * 0.5; + [[NSGraphicsContext currentContext] saveGraphicsState]; + CGContextRef context = + (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]); + CGContextBeginTransparencyLayer(context, 0); + if (!selected) + CGContextSetAlpha(context, backgroundAlpha); + [path addClip]; + [super drawRect:rect]; + + // Draw a mouse hover gradient for the default themes + if (!selected) { + if (![theme backgroundImageForStyle:GTMThemeStyleTabBarDeselected + state:GTMThemeStateActiveWindow]) { + scoped_nsobject<NSGradient> glow([NSGradient alloc]); + [glow initWithStartingColor:[NSColor colorWithCalibratedWhite:1.0 + alpha:1.0 * + hoverAlpha_] + endingColor:[NSColor colorWithCalibratedWhite:1.0 + alpha:0.0]]; + + NSPoint point = hoverPoint_; + point.y = NSHeight(rect); + [glow drawFromCenter:point + radius:0 + toCenter:point + radius:NSWidth(rect)/3 + options:NSGradientDrawsBeforeStartingLocation]; + + [glow drawInBezierPath:path relativeCenterPosition:hoverPoint_]; + } + } + + CGContextEndTransparencyLayer(context); + [[NSGraphicsContext currentContext] restoreGraphicsState]; + } + + // Draw the top inner highlight. + NSAffineTransform* highlightTransform = [NSAffineTransform transform]; + [highlightTransform translateXBy:1 yBy:-1]; + scoped_nsobject<NSBezierPath> highlightPath([path copy]); + [highlightPath transformUsingAffineTransform:highlightTransform]; + [[NSColor colorWithCalibratedWhite:1.0 alpha:0.2 + 0.3 * hoverAlpha_] + setStroke]; + [highlightPath stroke]; + + [[NSGraphicsContext currentContext] restoreGraphicsState]; + + // Draw the top stroke. + [[NSGraphicsContext currentContext] saveGraphicsState]; + if (selected) { + [[NSColor colorWithDeviceWhite:0.0 alpha:active ? 0.3 : 0.15] set]; + } else { + [[NSColor colorWithDeviceWhite:0.0 alpha:active ? 0.2 : 0.15] set]; + [[NSBezierPath bezierPathWithRect:NSOffsetRect(rect, 0, 2.5)] addClip]; + } + [path setLineWidth:1.0]; + [path stroke]; [[NSGraphicsContext currentContext] restoreGraphicsState]; // Draw the bottom border. if (!selected) { [path addClip]; NSRect borderRect, contentRect; - NSDivideRect(rect, &borderRect, &contentRect, 1, NSMinYEdge); - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.4] set]; + NSDivideRect(rect, &borderRect, &contentRect, 2.5, NSMinYEdge); + [[NSColor colorWithDeviceWhite:0.0 alpha:active ? 0.3 : 0.15] set]; NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); } [[NSGraphicsContext currentContext] restoreGraphicsState]; |