Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: chrome/browser/cocoa/tab_view.mm

Issue 181002: Reverting 24700. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/cocoa/tab_view.h ('k') | chrome/browser/cocoa/tab_view_unittest.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/cocoa/nsimage_cache.h" 5 #include "chrome/browser/cocoa/nsimage_cache.h"
6 #include "chrome/browser/cocoa/tab_controller.h" 6 #include "chrome/browser/cocoa/tab_controller.h"
7 #include "chrome/browser/cocoa/tab_view.h" 7 #include "chrome/browser/cocoa/tab_view.h"
8 #include "chrome/browser/cocoa/tab_window_controller.h" 8 #include "chrome/browser/cocoa/tab_window_controller.h"
9 9
10 10
11 // Constants for inset and control points for tab shape. 11 // Constants for inset and control points for tab shape.
12 static const CGFloat kInsetMultiplier = 2.0/3.0; 12 static const CGFloat kInsetMultiplier = 2.0/3.0;
13 static const CGFloat kControlPoint1Multiplier = 1.0/3.0; 13 static const CGFloat kControlPoint1Multiplier = 1.0/3.0;
14 static const CGFloat kControlPoint2Multiplier = 3.0/8.0; 14 static const CGFloat kControlPoint2Multiplier = 3.0/8.0;
15 15
16 static const NSTimeInterval kAnimationShowDuration = 0.2;
17 static const NSTimeInterval kAnimationHideDuration = 0.4;
18
19 @implementation TabView 16 @implementation TabView
20 17
21 @synthesize state = state_; 18 @synthesize state = state_;
22 @synthesize hoverAlpha = hoverAlpha_;
23 19
24 - (id)initWithFrame:(NSRect)frame { 20 - (id)initWithFrame:(NSRect)frame {
25 self = [super initWithFrame:frame]; 21 self = [super initWithFrame:frame];
26 if (self) { 22 if (self) {
27 chromeIsVisible_ = YES; 23 chromeIsVisible_ = YES;
28 [self setShowsDivider:NO]; 24 [self setShowsDivider:NO];
29 // TODO(alcor): register for theming, either here or the cell 25 // TODO(alcor): register for theming, either here or the cell
30 // [self gtm_registerForThemeNotifications]; 26 // [self gtm_registerForThemeNotifications];
31 } 27 }
32 return self; 28 return self;
33 } 29 }
34 30
35 - (void)awakeFromNib { 31 - (void)awakeFromNib {
36 [self setShowsDivider:NO]; 32 [self setShowsDivider:NO];
37 // Set up the tracking rect for the close button mouseover. Add it 33 // Set up the tracking rect for the close button mouseover. Add it
38 // to the |closeButton_| view, but we'll handle the message ourself. 34 // to the |closeButton_| view, but we'll handle the message ourself.
39 // The mouseover is always enabled, because the close button works 35 // The mouseover is always enabled, because the close button works
40 // regardless of key/main/active status. 36 // regardless of key/main/active status.
41 closeTrackingArea_.reset( 37 trackingArea_.reset(
42 [[NSTrackingArea alloc] initWithRect:[closeButton_ bounds] 38 [[NSTrackingArea alloc] initWithRect:[closeButton_ bounds]
43 options:NSTrackingMouseEnteredAndExited | 39 options:NSTrackingMouseEnteredAndExited |
44 NSTrackingActiveAlways 40 NSTrackingActiveAlways
45 owner:self 41 owner:self
46 userInfo:nil]); 42 userInfo:nil]);
47 [closeButton_ addTrackingArea:closeTrackingArea_.get()]; 43 [closeButton_ addTrackingArea:trackingArea_.get()];
48 } 44 }
49 45
50 - (void)dealloc { 46 - (void)dealloc {
51 // [self gtm_unregisterForThemeNotifications]; 47 // [self gtm_unregisterForThemeNotifications];
52 [closeButton_ removeTrackingArea:closeTrackingArea_.get()]; 48 [closeButton_ removeTrackingArea:trackingArea_.get()];
53 [super dealloc]; 49 [super dealloc];
54 } 50 }
55 51
56 // Overridden so that mouse clicks come to this view (the parent of the 52 // Overridden so that mouse clicks come to this view (the parent of the
57 // hierarchy) first. We want to handle clicks and drags in this class and 53 // hierarchy) first. We want to handle clicks and drags in this class and
58 // leave the background button for display purposes only. 54 // leave the background button for display purposes only.
59 - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { 55 - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent {
60 return YES; 56 return YES;
61 } 57 }
62 58
63 - (void)adjustHoverValue {
64 NSTimeInterval thisUpdate = [NSDate timeIntervalSinceReferenceDate];
65
66 NSTimeInterval elapsed = thisUpdate - lastHoverUpdate_;
67
68 CGFloat opacity = [self hoverAlpha];
69 if (isMouseInside_) {
70 opacity += elapsed / kAnimationShowDuration;
71 } else {
72 opacity -= elapsed / kAnimationHideDuration;
73 }
74
75 if (!isMouseInside_ && opacity < 0) {
76 opacity = 0;
77 } else if (isMouseInside_ && opacity > 1) {
78 opacity = 1;
79 } else {
80 [self performSelector:_cmd withObject:nil afterDelay:0.02];
81 }
82 lastHoverUpdate_ = thisUpdate;
83 [self setHoverAlpha:opacity];
84
85 [self setNeedsDisplay:YES];
86 }
87
88 - (void)mouseEntered:(NSEvent *)theEvent { 59 - (void)mouseEntered:(NSEvent *)theEvent {
89 if ([theEvent trackingArea] == closeTrackingArea_) { 60 // We only set up one tracking area, so we know any mouseEntered:
90 [closeButton_ setImage:nsimage_cache::ImageNamed(@"close_bar_h.pdf")]; 61 // messages are for close button mouseovers.
91 } else { 62 [closeButton_ setImage:nsimage_cache::ImageNamed(@"close_bar_h.pdf")];
92 lastHoverUpdate_ = [NSDate timeIntervalSinceReferenceDate];
93 isMouseInside_ = YES;
94 [self adjustHoverValue];
95 [self setNeedsDisplay:YES];
96 }
97 }
98
99 - (void)mouseMoved:(NSEvent *)theEvent {
100 hoverPoint_ = [self convertPoint:[theEvent locationInWindow]
101 fromView:nil];
102 [self setNeedsDisplay:YES];
103 } 63 }
104 64
105 - (void)mouseExited:(NSEvent *)theEvent { 65 - (void)mouseExited:(NSEvent *)theEvent {
106 if ([theEvent trackingArea] == closeTrackingArea_) { 66 // We only set up one tracking area, so we know any mouseExited:
107 [closeButton_ setImage:nsimage_cache::ImageNamed(@"close_bar.pdf")]; 67 // messages are for close button mouseovers.
108 } else { 68 [closeButton_ setImage:nsimage_cache::ImageNamed(@"close_bar.pdf")];
109 lastHoverUpdate_ = [NSDate timeIntervalSinceReferenceDate];
110 isMouseInside_ = NO;
111 [self adjustHoverValue];
112 [self setNeedsDisplay:YES];
113 }
114 } 69 }
115 70
116 // Determines which view a click in our frame actually hit. It's either this 71 // Determines which view a click in our frame actually hit. It's either this
117 // view or our child close button. 72 // view or our child close button.
118 - (NSView *)hitTest:(NSPoint)aPoint { 73 - (NSView *)hitTest:(NSPoint)aPoint {
119 NSPoint viewPoint = [self convertPoint:aPoint fromView:[self superview]]; 74 NSPoint viewPoint = [self convertPoint:aPoint fromView:[self superview]];
120 NSRect frame = [self frame]; 75 NSRect frame = [self frame];
121 76
122 // Reduce the width of the hit rect slightly to remove the overlap 77 // Reduce the width of the hit rect slightly to remove the overlap
123 // between adjacent tabs. The drawing code in TabCell has the top 78 // between adjacent tabs. The drawing code in TabCell has the top
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 } 224 }
270 } 225 }
271 226
272 // Iterate over possible targets checking for the one the mouse is in. 227 // Iterate over possible targets checking for the one the mouse is in.
273 // The mouse can be in either the tab or window frame. 228 // The mouse can be in either the tab or window frame.
274 TabWindowController* newTarget = nil; 229 TabWindowController* newTarget = nil;
275 for (TabWindowController* target in targets) { 230 for (TabWindowController* target in targets) {
276 NSRect windowFrame = [[target window] frame]; 231 NSRect windowFrame = [[target window] frame];
277 if (NSPointInRect(thisPoint, windowFrame)) { 232 if (NSPointInRect(thisPoint, windowFrame)) {
278 NSRect tabStripFrame = [[target tabStripView] frame]; 233 NSRect tabStripFrame = [[target tabStripView] frame];
234 tabStripFrame = [[target tabStripView] convertRectToBase:tabStripFrame];
279 tabStripFrame.origin = [[target window] 235 tabStripFrame.origin = [[target window]
280 convertBaseToScreen:tabStripFrame.origin]; 236 convertBaseToScreen:tabStripFrame.origin];
281 if (NSPointInRect(thisPoint, tabStripFrame)) { 237 if (NSPointInRect(thisPoint, tabStripFrame)) {
282 newTarget = target; 238 newTarget = target;
283 } 239 }
284 break; 240 break;
285 } 241 }
286 } 242 }
287 243
288 // If we're now targeting a new window, re-layout the tabs in the old 244 // If we're now targeting a new window, re-layout the tabs in the old
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 419
464 - (void)drawRect:(NSRect)rect { 420 - (void)drawRect:(NSRect)rect {
465 [[NSGraphicsContext currentContext] saveGraphicsState]; 421 [[NSGraphicsContext currentContext] saveGraphicsState];
466 rect = [self bounds]; 422 rect = [self bounds];
467 BOOL active = [[self window] isKeyWindow] || [[self window] isMainWindow]; 423 BOOL active = [[self window] isKeyWindow] || [[self window] isMainWindow];
468 BOOL selected = [(NSButton *)self state]; 424 BOOL selected = [(NSButton *)self state];
469 425
470 // Inset by 0.5 in order to draw on pixels rather than on borders (which would 426 // Inset by 0.5 in order to draw on pixels rather than on borders (which would
471 // cause blurry pixels). Decrease height by 1 in order to move away from the 427 // cause blurry pixels). Decrease height by 1 in order to move away from the
472 // edge for the dark shadow. 428 // edge for the dark shadow.
473 rect = NSInsetRect(rect, -0.5, -0.5); 429 rect = NSInsetRect(rect, 0.5, -0.5);
474 rect.origin.y -= 1; 430 rect.origin.y -= 1;
475 431
476 NSPoint bottomLeft = NSMakePoint(NSMinX(rect), NSMinY(rect) + 2); 432 NSPoint bottomLeft = NSMakePoint(NSMinX(rect), NSMinY(rect));
477 NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect) + 2); 433 NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect));
478 NSPoint topRight = 434 NSPoint topRight =
479 NSMakePoint(NSMaxX(rect) - kInsetMultiplier * NSHeight(rect), 435 NSMakePoint(NSMaxX(rect) - kInsetMultiplier * NSHeight(rect),
480 NSMaxY(rect)); 436 NSMaxY(rect));
481 NSPoint topLeft = 437 NSPoint topLeft =
482 NSMakePoint(NSMinX(rect) + kInsetMultiplier * NSHeight(rect), 438 NSMakePoint(NSMinX(rect) + kInsetMultiplier * NSHeight(rect),
483 NSMaxY(rect)); 439 NSMaxY(rect));
484 440
485 float baseControlPointOutset = NSHeight(rect) * kControlPoint1Multiplier; 441 float baseControlPointOutset = NSHeight(rect) * kControlPoint1Multiplier;
486 float bottomControlPointInset = NSHeight(rect) * kControlPoint2Multiplier; 442 float bottomControlPointInset = NSHeight(rect) * kControlPoint2Multiplier;
487 443
488 // Outset many of these values by 1 to cause the fill to bleed outside the 444 // Outset many of these values by 1 to cause the fill to bleed outside the
489 // clip area. 445 // clip area.
490 NSBezierPath *path = [NSBezierPath bezierPath]; 446 NSBezierPath *path = [NSBezierPath bezierPath];
491 [path moveToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y - 2)]; 447 [path moveToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y + 1)];
492 [path lineToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y)]; 448 [path lineToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y)];
493 [path lineToPoint:bottomLeft]; 449 [path lineToPoint:bottomLeft];
494 [path curveToPoint:topLeft 450 [path curveToPoint:topLeft
495 controlPoint1:NSMakePoint(bottomLeft.x + baseControlPointOutset, 451 controlPoint1:NSMakePoint(bottomLeft.x + baseControlPointOutset,
496 bottomLeft.y) 452 bottomLeft.y)
497 controlPoint2:NSMakePoint(topLeft.x - bottomControlPointInset, 453 controlPoint2:NSMakePoint(topLeft.x - bottomControlPointInset,
498 topLeft.y)]; 454 topLeft.y)];
499 [path lineToPoint:topRight]; 455 [path lineToPoint:topRight];
500 [path curveToPoint:bottomRight 456 [path curveToPoint:bottomRight
501 controlPoint1:NSMakePoint(topRight.x + bottomControlPointInset, 457 controlPoint1:NSMakePoint(topRight.x + bottomControlPointInset,
502 topRight.y) 458 topRight.y)
503 controlPoint2:NSMakePoint(bottomRight.x - baseControlPointOutset, 459 controlPoint2:NSMakePoint(bottomRight.x - baseControlPointOutset,
504 bottomRight.y)]; 460 bottomRight.y)];
505 [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y)]; 461 [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y)];
506 [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y - 2)]; 462 [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y + 1)];
463
464 if (selected) {
465 // Stroke with a translucent black.
466 [[NSColor colorWithCalibratedWhite:0.0 alpha:active ? 0.5 : 0.3] set];
467 [[NSGraphicsContext currentContext] saveGraphicsState];
468 scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]);
469 [shadow setShadowOffset:NSMakeSize(2, -1)];
470 [shadow setShadowBlurRadius:2.0];
471 [path fill];
472 [[NSGraphicsContext currentContext] restoreGraphicsState];
473 } else {
474 // Stroke with a translucent black.
475 [[NSBezierPath bezierPathWithRect:NSOffsetRect([self bounds], 0, 1)]
476 addClip];
477
478 [[NSColor colorWithCalibratedWhite:0.0 alpha:active ? 0.3 : 0.1] set];
479 }
480
481 [[NSGraphicsContext currentContext] saveGraphicsState];
482 [[NSColor colorWithCalibratedWhite:0.0 alpha:0.2] set];
483 [path setLineWidth:selected ? 2.0 : 1.0];
484 [path stroke];
485 [[NSGraphicsContext currentContext] restoreGraphicsState];
507 486
508 GTMTheme *theme = [self gtm_theme]; 487 GTMTheme *theme = [self gtm_theme];
509 488
510 if (!selected) { 489 if (!selected) {
511 NSColor *windowColor = 490 NSColor *windowColor =
512 [theme backgroundPatternColorForStyle:GTMThemeStyleWindow 491 [theme backgroundPatternColorForStyle:GTMThemeStyleWindow
513 state:GTMThemeStateActiveWindow]; 492 state:GTMThemeStateActiveWindow];
514 if (windowColor) { 493 if (windowColor) {
494 NSPoint phase = [self patternPhase];
515 [windowColor set]; 495 [windowColor set];
516 496 [[NSGraphicsContext currentContext] setPatternPhase:phase];
517 [[NSGraphicsContext currentContext] setPatternPhase:[self patternPhase]];
518 } else { 497 } else {
519 NSPoint phase = [self patternPhase]; 498 [[NSColor colorWithCalibratedWhite:0.6 alpha:1.0] set];
520 phase.y += 1;
521 [[NSGraphicsContext currentContext] setPatternPhase:phase];
522 [[NSColor windowBackgroundColor] set];
523 }
524
525 [path fill];
526
527 NSColor *tabColor =
528 [theme backgroundPatternColorForStyle:GTMThemeStyleTabBarDeselected
529 state:GTMThemeStateActiveWindow];
530 if (tabColor) {
531 [tabColor set];
532 [[NSGraphicsContext currentContext] setPatternPhase:[self patternPhase]];
533 } else {
534 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.3] set];
535 } 499 }
536 [path fill]; 500 [path fill];
537
538 } 501 }
539 502
503 // Draw the background.
540 [[NSGraphicsContext currentContext] saveGraphicsState]; 504 [[NSGraphicsContext currentContext] saveGraphicsState];
505 CGContextRef context =
506 (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]);
507 CGContextBeginTransparencyLayer(context, 0);
508 if (!selected)
509 CGContextSetAlpha(context, 0.5);
541 [path addClip]; 510 [path addClip];
511 [super drawRect:rect];
542 512
543 if (selected || hoverAlpha_ > 0) { 513 CGContextEndTransparencyLayer(context);
544 // Draw the background.
545 CGFloat backgroundAlpha = hoverAlpha_ * 0.5;
546 [[NSGraphicsContext currentContext] saveGraphicsState];
547 CGContextRef context =
548 (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]);
549 CGContextBeginTransparencyLayer(context, 0);
550 if (!selected)
551 CGContextSetAlpha(context, backgroundAlpha);
552 [path addClip];
553 [super drawRect:rect];
554
555 // Draw a mouse hover gradient for the default themes
556 if (!selected) {
557 if (![theme backgroundImageForStyle:GTMThemeStyleTabBarDeselected
558 state:GTMThemeStateActiveWindow]) {
559 scoped_nsobject<NSGradient> glow([NSGradient alloc]);
560 [glow initWithStartingColor:[NSColor colorWithCalibratedWhite:1.0
561 alpha:1.0 *
562 hoverAlpha_]
563 endingColor:[NSColor colorWithCalibratedWhite:1.0
564 alpha:0.0]];
565
566 NSPoint point = hoverPoint_;
567 point.y = NSHeight(rect);
568 [glow drawFromCenter:point
569 radius:0
570 toCenter:point
571 radius:NSWidth(rect)/3
572 options:NSGradientDrawsBeforeStartingLocation];
573
574 [glow drawInBezierPath:path relativeCenterPosition:hoverPoint_];
575 }
576 }
577
578 CGContextEndTransparencyLayer(context);
579 [[NSGraphicsContext currentContext] restoreGraphicsState];
580 }
581
582 // Draw the top inner highlight.
583 NSAffineTransform* highlightTransform = [NSAffineTransform transform];
584 [highlightTransform translateXBy:1 yBy:-1];
585 scoped_nsobject<NSBezierPath> highlightPath([path copy]);
586 [highlightPath transformUsingAffineTransform:highlightTransform];
587 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.2 + 0.3 * hoverAlpha_]
588 setStroke];
589 [highlightPath stroke];
590
591 [[NSGraphicsContext currentContext] restoreGraphicsState];
592
593 // Draw the top stroke.
594 [[NSGraphicsContext currentContext] saveGraphicsState];
595 if (selected) {
596 [[NSColor colorWithDeviceWhite:0.0 alpha:active ? 0.3 : 0.15] set];
597 } else {
598 [[NSColor colorWithDeviceWhite:0.0 alpha:active ? 0.2 : 0.15] set];
599 [[NSBezierPath bezierPathWithRect:NSOffsetRect(rect, 0, 2.5)] addClip];
600 }
601 [path setLineWidth:1.0];
602 [path stroke];
603 [[NSGraphicsContext currentContext] restoreGraphicsState]; 514 [[NSGraphicsContext currentContext] restoreGraphicsState];
604 515
605 // Draw the bottom border. 516 // Draw the bottom border.
606 if (!selected) { 517 if (!selected) {
607 [path addClip]; 518 [path addClip];
608 NSRect borderRect, contentRect; 519 NSRect borderRect, contentRect;
609 NSDivideRect(rect, &borderRect, &contentRect, 2.5, NSMinYEdge); 520 NSDivideRect(rect, &borderRect, &contentRect, 1, NSMinYEdge);
610 [[NSColor colorWithDeviceWhite:0.0 alpha:active ? 0.3 : 0.15] set]; 521 [[NSColor colorWithCalibratedWhite:0.0 alpha:0.4] set];
611 NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); 522 NSRectFillUsingOperation(borderRect, NSCompositeSourceOver);
612 } 523 }
613 [[NSGraphicsContext currentContext] restoreGraphicsState]; 524 [[NSGraphicsContext currentContext] restoreGraphicsState];
614 } 525 }
615 526
616 // Called when the user hits the right mouse button (or control-clicks) to 527 // Called when the user hits the right mouse button (or control-clicks) to
617 // show a context menu. 528 // show a context menu.
618 - (void)rightMouseDown:(NSEvent*)theEvent { 529 - (void)rightMouseDown:(NSEvent*)theEvent {
619 [NSMenu popUpContextMenu:[self menu] withEvent:theEvent forView:self]; 530 [NSMenu popUpContextMenu:[self menu] withEvent:theEvent forView:self];
620 } 531 }
621 532
622 @end 533 @end
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/tab_view.h ('k') | chrome/browser/cocoa/tab_view_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698