| OLD | NEW |
| 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 #import "chrome/browser/cocoa/tab_view.h" | 5 #import "chrome/browser/cocoa/tab_view.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/nsimage_cache_mac.h" | 8 #include "base/nsimage_cache_mac.h" |
| 9 #import "chrome/browser/cocoa/tab_controller.h" | 9 #import "chrome/browser/cocoa/tab_controller.h" |
| 10 #import "chrome/browser/cocoa/tab_window_controller.h" | 10 #import "chrome/browser/cocoa/tab_window_controller.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 // Cancel any delayed requests that may still be pending (drags or hover). | 52 // Cancel any delayed requests that may still be pending (drags or hover). |
| 53 [NSObject cancelPreviousPerformRequestsWithTarget:self]; | 53 [NSObject cancelPreviousPerformRequestsWithTarget:self]; |
| 54 // [self gtm_unregisterForThemeNotifications]; | 54 // [self gtm_unregisterForThemeNotifications]; |
| 55 [closeButton_ removeTrackingArea:closeTrackingArea_.get()]; | 55 [closeButton_ removeTrackingArea:closeTrackingArea_.get()]; |
| 56 [super dealloc]; | 56 [super dealloc]; |
| 57 } | 57 } |
| 58 | 58 |
| 59 // Overridden so that mouse clicks come to this view (the parent of the | 59 // Overridden so that mouse clicks come to this view (the parent of the |
| 60 // hierarchy) first. We want to handle clicks and drags in this class and | 60 // hierarchy) first. We want to handle clicks and drags in this class and |
| 61 // leave the background button for display purposes only. | 61 // leave the background button for display purposes only. |
| 62 - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { | 62 - (BOOL)acceptsFirstMouse:(NSEvent*)theEvent { |
| 63 return YES; | 63 return YES; |
| 64 } | 64 } |
| 65 | 65 |
| 66 - (void)adjustHoverValue { | 66 - (void)adjustHoverValue { |
| 67 NSTimeInterval thisUpdate = [NSDate timeIntervalSinceReferenceDate]; | 67 NSTimeInterval thisUpdate = [NSDate timeIntervalSinceReferenceDate]; |
| 68 | 68 |
| 69 NSTimeInterval elapsed = thisUpdate - lastHoverUpdate_; | 69 NSTimeInterval elapsed = thisUpdate - lastHoverUpdate_; |
| 70 | 70 |
| 71 CGFloat opacity = [self hoverAlpha]; | 71 CGFloat opacity = [self hoverAlpha]; |
| 72 if (isMouseInside_) { | 72 if (isMouseInside_) { |
| 73 opacity += elapsed / kAnimationShowDuration; | 73 opacity += elapsed / kAnimationShowDuration; |
| 74 } else { | 74 } else { |
| 75 opacity -= elapsed / kAnimationHideDuration; | 75 opacity -= elapsed / kAnimationHideDuration; |
| 76 } | 76 } |
| 77 | 77 |
| 78 if (!isMouseInside_ && opacity < 0) { | 78 if (!isMouseInside_ && opacity < 0) { |
| 79 opacity = 0; | 79 opacity = 0; |
| 80 } else if (isMouseInside_ && opacity > 1) { | 80 } else if (isMouseInside_ && opacity > 1) { |
| 81 opacity = 1; | 81 opacity = 1; |
| 82 } else { | 82 } else { |
| 83 [self performSelector:_cmd withObject:nil afterDelay:0.02]; | 83 [self performSelector:_cmd withObject:nil afterDelay:0.02]; |
| 84 } | 84 } |
| 85 lastHoverUpdate_ = thisUpdate; | 85 lastHoverUpdate_ = thisUpdate; |
| 86 [self setHoverAlpha:opacity]; | 86 [self setHoverAlpha:opacity]; |
| 87 | 87 |
| 88 [self setNeedsDisplay:YES]; | 88 [self setNeedsDisplay:YES]; |
| 89 } | 89 } |
| 90 | 90 |
| 91 - (void)mouseEntered:(NSEvent *)theEvent { | 91 - (void)mouseEntered:(NSEvent*)theEvent { |
| 92 if ([theEvent trackingArea] == closeTrackingArea_) { | 92 if ([theEvent trackingArea] == closeTrackingArea_) { |
| 93 [closeButton_ setImage:nsimage_cache::ImageNamed(@"close_bar_h.pdf")]; | 93 [closeButton_ setImage:nsimage_cache::ImageNamed(@"close_bar_h.pdf")]; |
| 94 } else { | 94 } else { |
| 95 lastHoverUpdate_ = [NSDate timeIntervalSinceReferenceDate]; | 95 lastHoverUpdate_ = [NSDate timeIntervalSinceReferenceDate]; |
| 96 isMouseInside_ = YES; | 96 isMouseInside_ = YES; |
| 97 [self adjustHoverValue]; | 97 [self adjustHoverValue]; |
| 98 [self setNeedsDisplay:YES]; | 98 [self setNeedsDisplay:YES]; |
| 99 } | 99 } |
| 100 } | 100 } |
| 101 | 101 |
| 102 - (void)mouseMoved:(NSEvent *)theEvent { | 102 - (void)mouseMoved:(NSEvent*)theEvent { |
| 103 hoverPoint_ = [self convertPoint:[theEvent locationInWindow] | 103 hoverPoint_ = [self convertPoint:[theEvent locationInWindow] |
| 104 fromView:nil]; | 104 fromView:nil]; |
| 105 [self setNeedsDisplay:YES]; | 105 [self setNeedsDisplay:YES]; |
| 106 } | 106 } |
| 107 | 107 |
| 108 - (void)mouseExited:(NSEvent *)theEvent { | 108 - (void)mouseExited:(NSEvent*)theEvent { |
| 109 if ([theEvent trackingArea] == closeTrackingArea_) { | 109 if ([theEvent trackingArea] == closeTrackingArea_) { |
| 110 [closeButton_ setImage:nsimage_cache::ImageNamed(@"close_bar.pdf")]; | 110 [closeButton_ setImage:nsimage_cache::ImageNamed(@"close_bar.pdf")]; |
| 111 } else { | 111 } else { |
| 112 lastHoverUpdate_ = [NSDate timeIntervalSinceReferenceDate]; | 112 lastHoverUpdate_ = [NSDate timeIntervalSinceReferenceDate]; |
| 113 isMouseInside_ = NO; | 113 isMouseInside_ = NO; |
| 114 [self adjustHoverValue]; | 114 [self adjustHoverValue]; |
| 115 [self setNeedsDisplay:YES]; | 115 [self setNeedsDisplay:YES]; |
| 116 } | 116 } |
| 117 } | 117 } |
| 118 | 118 |
| 119 // Determines which view a click in our frame actually hit. It's either this | 119 // Determines which view a click in our frame actually hit. It's either this |
| 120 // view or our child close button. | 120 // view or our child close button. |
| 121 - (NSView *)hitTest:(NSPoint)aPoint { | 121 - (NSView*)hitTest:(NSPoint)aPoint { |
| 122 NSPoint viewPoint = [self convertPoint:aPoint fromView:[self superview]]; | 122 NSPoint viewPoint = [self convertPoint:aPoint fromView:[self superview]]; |
| 123 NSRect frame = [self frame]; | 123 NSRect frame = [self frame]; |
| 124 | 124 |
| 125 // Reduce the width of the hit rect slightly to remove the overlap | 125 // Reduce the width of the hit rect slightly to remove the overlap |
| 126 // between adjacent tabs. The drawing code in TabCell has the top | 126 // between adjacent tabs. The drawing code in TabCell has the top |
| 127 // corners of the tab inset by height*2/3, so we inset by half of | 127 // corners of the tab inset by height*2/3, so we inset by half of |
| 128 // that here. This doesn't completely eliminate the overlap, but it | 128 // that here. This doesn't completely eliminate the overlap, but it |
| 129 // works well enough. | 129 // works well enough. |
| 130 NSRect hitRect = NSInsetRect(frame, frame.size.height / 3.0f, 0); | 130 NSRect hitRect = NSInsetRect(frame, frame.size.height / 3.0f, 0); |
| 131 if (![closeButton_ isHidden]) | 131 if (![closeButton_ isHidden]) |
| 132 if (NSPointInRect(viewPoint, [closeButton_ frame])) return closeButton_; | 132 if (NSPointInRect(viewPoint, [closeButton_ frame])) return closeButton_; |
| 133 if (NSPointInRect(aPoint, hitRect)) return self; | 133 if (NSPointInRect(aPoint, hitRect)) return self; |
| 134 return nil; | 134 return nil; |
| 135 } | 135 } |
| 136 | 136 |
| 137 // Returns |YES| if this tab can be torn away into a new window. | 137 // Returns |YES| if this tab can be torn away into a new window. |
| 138 - (BOOL)canBeDragged { | 138 - (BOOL)canBeDragged { |
| 139 NSWindowController *controller = [sourceWindow_ windowController]; | 139 NSWindowController* controller = [sourceWindow_ windowController]; |
| 140 if ([controller isKindOfClass:[TabWindowController class]]) { | 140 if ([controller isKindOfClass:[TabWindowController class]]) { |
| 141 TabWindowController* realController = | 141 TabWindowController* realController = |
| 142 static_cast<TabWindowController*>(controller); | 142 static_cast<TabWindowController*>(controller); |
| 143 return [realController isTabDraggable:self]; | 143 return [realController isTabDraggable:self]; |
| 144 } | 144 } |
| 145 return YES; | 145 return YES; |
| 146 } | 146 } |
| 147 | 147 |
| 148 // Find all the windows that could be a target. It has to be of the | 148 // Find all the windows that could be a target. It has to be of the |
| 149 // appropriate class, and visible (obviously). Note that the window cannot be | 149 // appropriate class, and visible (obviously). Note that the window cannot be |
| 150 // a target for itself. | 150 // a target for itself. |
| 151 - (NSArray*)dropTargetsForController:(TabWindowController*)dragController { | 151 - (NSArray*)dropTargetsForController:(TabWindowController*)dragController { |
| 152 NSMutableArray* targets = [NSMutableArray array]; | 152 NSMutableArray* targets = [NSMutableArray array]; |
| 153 NSWindow* dragWindow = [dragController window]; | 153 NSWindow* dragWindow = [dragController window]; |
| 154 for (NSWindow* window in [NSApp windows]) { | 154 for (NSWindow* window in [NSApp windows]) { |
| 155 if (window == dragWindow) continue; | 155 if (window == dragWindow) continue; |
| 156 if (![window isVisible]) continue; | 156 if (![window isVisible]) continue; |
| 157 NSWindowController *controller = [window windowController]; | 157 NSWindowController* controller = [window windowController]; |
| 158 if ([controller isKindOfClass:[TabWindowController class]]) { | 158 if ([controller isKindOfClass:[TabWindowController class]]) { |
| 159 TabWindowController* realController = | 159 TabWindowController* realController = |
| 160 static_cast<TabWindowController*>(controller); | 160 static_cast<TabWindowController*>(controller); |
| 161 if ([realController canReceiveFrom:dragController]) { | 161 if ([realController canReceiveFrom:dragController]) { |
| 162 [targets addObject:controller]; | 162 [targets addObject:controller]; |
| 163 } | 163 } |
| 164 } | 164 } |
| 165 } | 165 } |
| 166 return targets; | 166 return targets; |
| 167 } | 167 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 182 // ideas of dragging cocoa views between windows and how the Browser and | 182 // ideas of dragging cocoa views between windows and how the Browser and |
| 183 // TabStrip models want to manage tabs. | 183 // TabStrip models want to manage tabs. |
| 184 | 184 |
| 185 static const CGFloat kTearDistance = 36.0; | 185 static const CGFloat kTearDistance = 36.0; |
| 186 static const NSTimeInterval kTearDuration = 0.333; | 186 static const NSTimeInterval kTearDuration = 0.333; |
| 187 | 187 |
| 188 // This is used to judge whether the mouse has moved during rapid closure; if it | 188 // This is used to judge whether the mouse has moved during rapid closure; if it |
| 189 // has moved less than the threshold, we want to close the tab. | 189 // has moved less than the threshold, we want to close the tab. |
| 190 static const CGFloat kRapidCloseDist = 2.5; | 190 static const CGFloat kRapidCloseDist = 2.5; |
| 191 | 191 |
| 192 - (void)mouseDown:(NSEvent *)theEvent { | 192 - (void)mouseDown:(NSEvent*)theEvent { |
| 193 NSPoint downLocation = [theEvent locationInWindow]; | 193 NSPoint downLocation = [theEvent locationInWindow]; |
| 194 | 194 |
| 195 // During the tab closure animation (in particular, during rapid tab closure), | 195 // During the tab closure animation (in particular, during rapid tab closure), |
| 196 // we may get incorrectly hit with a mouse down. If it should have gone to the | 196 // we may get incorrectly hit with a mouse down. If it should have gone to the |
| 197 // close button, we send it there -- it should then track the mouse, so we | 197 // close button, we send it there -- it should then track the mouse, so we |
| 198 // don't have to worry about mouse ups. | 198 // don't have to worry about mouse ups. |
| 199 if ([controller_ inRapidClosureMode]) { | 199 if ([controller_ inRapidClosureMode]) { |
| 200 NSPoint hitLocation = [[self superview] convertPoint:downLocation | 200 NSPoint hitLocation = [[self superview] convertPoint:downLocation |
| 201 fromView:nil]; | 201 fromView:nil]; |
| 202 if ([self hitTest:hitLocation] == closeButton_) { | 202 if ([self hitTest:hitLocation] == closeButton_) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 } else { | 277 } else { |
| 278 // TODO(viettrungluu): [crbug.com/23830] We can receive right-mouse-ups | 278 // TODO(viettrungluu): [crbug.com/23830] We can receive right-mouse-ups |
| 279 // (and maybe even others?) for reasons I don't understand. So we | 279 // (and maybe even others?) for reasons I don't understand. So we |
| 280 // explicitly check for both events we're expecting, and log others. We | 280 // explicitly check for both events we're expecting, and log others. We |
| 281 // should figure out what's going on. | 281 // should figure out what's going on. |
| 282 LOG(WARNING) << "Spurious event received of type " << type << "."; | 282 LOG(WARNING) << "Spurious event received of type " << type << "."; |
| 283 } | 283 } |
| 284 } | 284 } |
| 285 } | 285 } |
| 286 | 286 |
| 287 - (void)mouseDragged:(NSEvent *)theEvent { | 287 - (void)mouseDragged:(NSEvent*)theEvent { |
| 288 // Special-case this to keep the logic below simpler. | 288 // Special-case this to keep the logic below simpler. |
| 289 if (moveWindowOnDrag_) { | 289 if (moveWindowOnDrag_) { |
| 290 NSPoint thisPoint = [NSEvent mouseLocation]; | 290 NSPoint thisPoint = [NSEvent mouseLocation]; |
| 291 NSPoint origin = sourceWindowFrame_.origin; | 291 NSPoint origin = sourceWindowFrame_.origin; |
| 292 origin.x += (thisPoint.x - dragOrigin_.x); | 292 origin.x += (thisPoint.x - dragOrigin_.x); |
| 293 origin.y += (thisPoint.y - dragOrigin_.y); | 293 origin.y += (thisPoint.y - dragOrigin_.y); |
| 294 [sourceWindow_ setFrameOrigin:NSMakePoint(origin.x, origin.y)]; | 294 [sourceWindow_ setFrameOrigin:NSMakePoint(origin.x, origin.y)]; |
| 295 return; | 295 return; |
| 296 } | 296 } |
| 297 | 297 |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 if (targetController_) { | 445 if (targetController_) { |
| 446 if (![[targetController_ window] isKeyWindow]) { | 446 if (![[targetController_ window] isKeyWindow]) { |
| 447 // && ([targetDwellDate timeIntervalSinceNow] < -REQUIRED_DWELL)) { | 447 // && ([targetDwellDate timeIntervalSinceNow] < -REQUIRED_DWELL)) { |
| 448 [[targetController_ window] orderFront:nil]; | 448 [[targetController_ window] orderFront:nil]; |
| 449 targetDwellDate = nil; | 449 targetDwellDate = nil; |
| 450 } | 450 } |
| 451 | 451 |
| 452 // Compute where placeholder should go and insert it into the | 452 // Compute where placeholder should go and insert it into the |
| 453 // destination tab strip. | 453 // destination tab strip. |
| 454 NSRect dropTabFrame = [[targetController_ tabStripView] frame]; | 454 NSRect dropTabFrame = [[targetController_ tabStripView] frame]; |
| 455 TabView *draggedTabView = (TabView *)[draggedController_ selectedTabView]; | 455 TabView* draggedTabView = (TabView*)[draggedController_ selectedTabView]; |
| 456 NSRect tabFrame = [draggedTabView frame]; | 456 NSRect tabFrame = [draggedTabView frame]; |
| 457 tabFrame.origin = [dragWindow_ convertBaseToScreen:tabFrame.origin]; | 457 tabFrame.origin = [dragWindow_ convertBaseToScreen:tabFrame.origin]; |
| 458 tabFrame.origin = [[targetController_ window] | 458 tabFrame.origin = [[targetController_ window] |
| 459 convertScreenToBase:tabFrame.origin]; | 459 convertScreenToBase:tabFrame.origin]; |
| 460 tabFrame = [[targetController_ tabStripView] | 460 tabFrame = [[targetController_ tabStripView] |
| 461 convertRectFromBase:tabFrame]; | 461 convertRectFromBase:tabFrame]; |
| 462 NSPoint point = | 462 NSPoint point = |
| 463 [sourceWindow_ convertBaseToScreen: | 463 [sourceWindow_ convertBaseToScreen: |
| 464 [draggedTabView convertPointToBase:NSZeroPoint]]; | 464 [draggedTabView convertPointToBase:NSZeroPoint]]; |
| 465 [targetController_ insertPlaceholderForTab:self | 465 [targetController_ insertPlaceholderForTab:self |
| (...skipping 17 matching lines...) Expand all Loading... |
| 483 [dragWindow_ setAlphaValue:0.0]; | 483 [dragWindow_ setAlphaValue:0.0]; |
| 484 [[draggedController_ overlayWindow] setHasShadow:YES]; | 484 [[draggedController_ overlayWindow] setHasShadow:YES]; |
| 485 } else { | 485 } else { |
| 486 [dragWindow_ setAlphaValue:0.5]; | 486 [dragWindow_ setAlphaValue:0.5]; |
| 487 [[draggedController_ overlayWindow] setHasShadow:NO]; | 487 [[draggedController_ overlayWindow] setHasShadow:NO]; |
| 488 } | 488 } |
| 489 chromeIsVisible_ = chromeShouldBeVisible; | 489 chromeIsVisible_ = chromeShouldBeVisible; |
| 490 } | 490 } |
| 491 } | 491 } |
| 492 | 492 |
| 493 - (void)mouseUp:(NSEvent *)theEvent { | 493 - (void)mouseUp:(NSEvent*)theEvent { |
| 494 // The drag/click is done. If the user dragged the mouse, finalize the drag | 494 // The drag/click is done. If the user dragged the mouse, finalize the drag |
| 495 // and clean up. | 495 // and clean up. |
| 496 | 496 |
| 497 // Special-case this to keep the logic below simpler. | 497 // Special-case this to keep the logic below simpler. |
| 498 if (moveWindowOnDrag_) | 498 if (moveWindowOnDrag_) |
| 499 return; | 499 return; |
| 500 | 500 |
| 501 // Cancel any delayed -mouseDragged: requests that may still be pending. | 501 // Cancel any delayed -mouseDragged: requests that may still be pending. |
| 502 [NSObject cancelPreviousPerformRequestsWithTarget:self]; | 502 [NSObject cancelPreviousPerformRequestsWithTarget:self]; |
| 503 | 503 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 [self resetDragControllers]; | 542 [self resetDragControllers]; |
| 543 } | 543 } |
| 544 | 544 |
| 545 - (void)otherMouseUp:(NSEvent*)theEvent { | 545 - (void)otherMouseUp:(NSEvent*)theEvent { |
| 546 // Support middle-click-to-close. | 546 // Support middle-click-to-close. |
| 547 if ([theEvent buttonNumber] == 2) { | 547 if ([theEvent buttonNumber] == 2) { |
| 548 [controller_ closeTab:self]; | 548 [controller_ closeTab:self]; |
| 549 } | 549 } |
| 550 } | 550 } |
| 551 | 551 |
| 552 - (NSPoint)patternPhase { | |
| 553 NSPoint phase = NSZeroPoint; | |
| 554 phase.x -= [self convertRect:[self bounds] toView:nil].origin.x; | |
| 555 // offset to start pattern in upper left corner | |
| 556 phase.y += NSHeight([self bounds]) - 1; | |
| 557 return phase; | |
| 558 } | |
| 559 | |
| 560 - (void)drawRect:(NSRect)rect { | 552 - (void)drawRect:(NSRect)rect { |
| 561 [[NSGraphicsContext currentContext] saveGraphicsState]; | 553 NSGraphicsContext* context = [NSGraphicsContext currentContext]; |
| 554 [context saveGraphicsState]; |
| 562 rect = [self bounds]; | 555 rect = [self bounds]; |
| 563 BOOL active = [[self window] isKeyWindow] || [[self window] isMainWindow]; | 556 BOOL active = [[self window] isKeyWindow] || [[self window] isMainWindow]; |
| 564 BOOL selected = [(NSButton *)self state]; | 557 BOOL selected = [(NSButton*)self state]; |
| 565 | 558 |
| 566 // Inset by 0.5 in order to draw on pixels rather than on borders (which would | 559 // Inset by 0.5 in order to draw on pixels rather than on borders (which would |
| 567 // cause blurry pixels). Decrease height by 1 in order to move away from the | 560 // cause blurry pixels). Decrease height by 1 in order to move away from the |
| 568 // edge for the dark shadow. | 561 // edge for the dark shadow. |
| 569 rect = NSInsetRect(rect, -0.5, -0.5); | 562 rect = NSInsetRect(rect, -0.5, -0.5); |
| 570 rect.origin.y -= 1; | 563 rect.origin.y -= 1; |
| 571 | 564 |
| 572 NSPoint bottomLeft = NSMakePoint(NSMinX(rect), NSMinY(rect) + 2); | 565 NSPoint bottomLeft = NSMakePoint(NSMinX(rect), NSMinY(rect) + 2); |
| 573 NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect) + 2); | 566 NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect) + 2); |
| 574 NSPoint topRight = | 567 NSPoint topRight = |
| 575 NSMakePoint(NSMaxX(rect) - kInsetMultiplier * NSHeight(rect), | 568 NSMakePoint(NSMaxX(rect) - kInsetMultiplier * NSHeight(rect), |
| 576 NSMaxY(rect)); | 569 NSMaxY(rect)); |
| 577 NSPoint topLeft = | 570 NSPoint topLeft = |
| 578 NSMakePoint(NSMinX(rect) + kInsetMultiplier * NSHeight(rect), | 571 NSMakePoint(NSMinX(rect) + kInsetMultiplier * NSHeight(rect), |
| 579 NSMaxY(rect)); | 572 NSMaxY(rect)); |
| 580 | 573 |
| 581 float baseControlPointOutset = NSHeight(rect) * kControlPoint1Multiplier; | 574 float baseControlPointOutset = NSHeight(rect) * kControlPoint1Multiplier; |
| 582 float bottomControlPointInset = NSHeight(rect) * kControlPoint2Multiplier; | 575 float bottomControlPointInset = NSHeight(rect) * kControlPoint2Multiplier; |
| 583 | 576 |
| 584 // Outset many of these values by 1 to cause the fill to bleed outside the | 577 // Outset many of these values by 1 to cause the fill to bleed outside the |
| 585 // clip area. | 578 // clip area. |
| 586 NSBezierPath *path = [NSBezierPath bezierPath]; | 579 NSBezierPath* path = [NSBezierPath bezierPath]; |
| 587 [path moveToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y - 2)]; | 580 [path moveToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y - 2)]; |
| 588 [path lineToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y)]; | 581 [path lineToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y)]; |
| 589 [path lineToPoint:bottomLeft]; | 582 [path lineToPoint:bottomLeft]; |
| 590 [path curveToPoint:topLeft | 583 [path curveToPoint:topLeft |
| 591 controlPoint1:NSMakePoint(bottomLeft.x + baseControlPointOutset, | 584 controlPoint1:NSMakePoint(bottomLeft.x + baseControlPointOutset, |
| 592 bottomLeft.y) | 585 bottomLeft.y) |
| 593 controlPoint2:NSMakePoint(topLeft.x - bottomControlPointInset, | 586 controlPoint2:NSMakePoint(topLeft.x - bottomControlPointInset, |
| 594 topLeft.y)]; | 587 topLeft.y)]; |
| 595 [path lineToPoint:topRight]; | 588 [path lineToPoint:topRight]; |
| 596 [path curveToPoint:bottomRight | 589 [path curveToPoint:bottomRight |
| 597 controlPoint1:NSMakePoint(topRight.x + bottomControlPointInset, | 590 controlPoint1:NSMakePoint(topRight.x + bottomControlPointInset, |
| 598 topRight.y) | 591 topRight.y) |
| 599 controlPoint2:NSMakePoint(bottomRight.x - baseControlPointOutset, | 592 controlPoint2:NSMakePoint(bottomRight.x - baseControlPointOutset, |
| 600 bottomRight.y)]; | 593 bottomRight.y)]; |
| 601 [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y)]; | 594 [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y)]; |
| 602 [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y - 2)]; | 595 [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y - 2)]; |
| 603 | 596 |
| 604 GTMTheme *theme = [self gtm_theme]; | 597 GTMTheme* theme = [self gtm_theme]; |
| 598 |
| 599 // Setting the pattern phase |
| 600 NSPoint phase = [self gtm_themePatternPhase]; |
| 601 [context setPatternPhase:phase]; |
| 605 | 602 |
| 606 if (!selected) { | 603 if (!selected) { |
| 607 NSColor *windowColor = | 604 NSColor* windowColor = |
| 608 [theme backgroundPatternColorForStyle:GTMThemeStyleWindow | 605 [theme backgroundPatternColorForStyle:GTMThemeStyleWindow |
| 609 state:GTMThemeStateActiveWindow]; | 606 state:GTMThemeStateActiveWindow]; |
| 610 if (windowColor) { | 607 if (windowColor) { |
| 611 [windowColor set]; | 608 [windowColor set]; |
| 612 | |
| 613 [[NSGraphicsContext currentContext] setPatternPhase:[self patternPhase]]; | |
| 614 } else { | 609 } else { |
| 615 NSPoint phase = [self patternPhase]; | |
| 616 phase.y += 1; | |
| 617 [[NSGraphicsContext currentContext] setPatternPhase:phase]; | |
| 618 [[NSColor windowBackgroundColor] set]; | 610 [[NSColor windowBackgroundColor] set]; |
| 619 } | 611 } |
| 620 | 612 |
| 621 [path fill]; | 613 [path fill]; |
| 622 | 614 |
| 623 NSColor *tabColor = | 615 NSColor* tabColor = |
| 624 [theme backgroundPatternColorForStyle:GTMThemeStyleTabBarDeselected | 616 [theme backgroundPatternColorForStyle:GTMThemeStyleTabBarDeselected |
| 625 state:GTMThemeStateActiveWindow]; | 617 state:GTMThemeStateActiveWindow]; |
| 626 if (tabColor) { | 618 if (tabColor) { |
| 627 [tabColor set]; | 619 [tabColor set]; |
| 628 [[NSGraphicsContext currentContext] setPatternPhase:[self patternPhase]]; | |
| 629 } else { | 620 } else { |
| 630 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.3] set]; | 621 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.3] set]; |
| 631 } | 622 } |
| 632 [path fill]; | 623 [path fill]; |
| 633 | |
| 634 } | 624 } |
| 635 | 625 |
| 636 [[NSGraphicsContext currentContext] saveGraphicsState]; | 626 [context saveGraphicsState]; |
| 637 [path addClip]; | 627 [path addClip]; |
| 638 | 628 |
| 639 if (selected || hoverAlpha_ > 0) { | 629 if (selected || hoverAlpha_ > 0) { |
| 640 // Draw the background. | 630 // Draw the background. |
| 641 CGFloat backgroundAlpha = hoverAlpha_ * 0.5; | 631 CGFloat backgroundAlpha = hoverAlpha_ * 0.5; |
| 642 [[NSGraphicsContext currentContext] saveGraphicsState]; | 632 [context saveGraphicsState]; |
| 643 CGContextRef context = | 633 CGContextRef cgContext = |
| 644 (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]); | 634 (CGContextRef)([context graphicsPort]); |
| 645 CGContextBeginTransparencyLayer(context, 0); | 635 CGContextBeginTransparencyLayer(cgContext, 0); |
| 646 if (!selected) | 636 if (!selected) |
| 647 CGContextSetAlpha(context, backgroundAlpha); | 637 CGContextSetAlpha(cgContext, backgroundAlpha); |
| 648 [path addClip]; | 638 [path addClip]; |
| 649 [super drawRect:rect]; | 639 [context saveGraphicsState]; |
| 640 [super drawBackground]; |
| 641 [context restoreGraphicsState]; |
| 650 | 642 |
| 651 // Draw a mouse hover gradient for the default themes | 643 // Draw a mouse hover gradient for the default themes |
| 652 if (!selected) { | 644 if (!selected) { |
| 653 if (![theme backgroundImageForStyle:GTMThemeStyleTabBarDeselected | 645 if (![theme backgroundImageForStyle:GTMThemeStyleTabBarDeselected |
| 654 state:GTMThemeStateActiveWindow]) { | 646 state:GTMThemeStateActiveWindow]) { |
| 655 scoped_nsobject<NSGradient> glow([NSGradient alloc]); | 647 scoped_nsobject<NSGradient> glow([NSGradient alloc]); |
| 656 [glow initWithStartingColor:[NSColor colorWithCalibratedWhite:1.0 | 648 [glow initWithStartingColor:[NSColor colorWithCalibratedWhite:1.0 |
| 657 alpha:1.0 * | 649 alpha:1.0 * |
| 658 hoverAlpha_] | 650 hoverAlpha_] |
| 659 endingColor:[NSColor colorWithCalibratedWhite:1.0 | 651 endingColor:[NSColor colorWithCalibratedWhite:1.0 |
| 660 alpha:0.0]]; | 652 alpha:0.0]]; |
| 661 | 653 |
| 662 NSPoint point = hoverPoint_; | 654 NSPoint point = hoverPoint_; |
| 663 point.y = NSHeight(rect); | 655 point.y = NSHeight(rect); |
| 664 [glow drawFromCenter:point | 656 [glow drawFromCenter:point |
| 665 radius:0 | 657 radius:0 |
| 666 toCenter:point | 658 toCenter:point |
| 667 radius:NSWidth(rect)/3 | 659 radius:NSWidth(rect)/3 |
| 668 options:NSGradientDrawsBeforeStartingLocation]; | 660 options:NSGradientDrawsBeforeStartingLocation]; |
| 669 | 661 |
| 670 [glow drawInBezierPath:path relativeCenterPosition:hoverPoint_]; | 662 [glow drawInBezierPath:path relativeCenterPosition:hoverPoint_]; |
| 671 } | 663 } |
| 672 } | 664 } |
| 673 | 665 |
| 674 CGContextEndTransparencyLayer(context); | 666 CGContextEndTransparencyLayer(cgContext); |
| 675 [[NSGraphicsContext currentContext] restoreGraphicsState]; | 667 [context restoreGraphicsState]; |
| 676 } | 668 } |
| 677 | 669 |
| 678 // Draw the top inner highlight. | 670 // Draw the top inner highlight. |
| 679 NSAffineTransform* highlightTransform = [NSAffineTransform transform]; | 671 NSAffineTransform* highlightTransform = [NSAffineTransform transform]; |
| 680 [highlightTransform translateXBy:1 yBy:-1]; | 672 [highlightTransform translateXBy:1 yBy:-1]; |
| 681 scoped_nsobject<NSBezierPath> highlightPath([path copy]); | 673 scoped_nsobject<NSBezierPath> highlightPath([path copy]); |
| 682 [highlightPath transformUsingAffineTransform:highlightTransform]; | 674 [highlightPath transformUsingAffineTransform:highlightTransform]; |
| 683 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.2 + 0.3 * hoverAlpha_] | 675 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.2 + 0.3 * hoverAlpha_] |
| 684 setStroke]; | 676 setStroke]; |
| 685 [highlightPath stroke]; | 677 [highlightPath stroke]; |
| 686 | 678 |
| 687 [[NSGraphicsContext currentContext] restoreGraphicsState]; | 679 [context restoreGraphicsState]; |
| 688 | 680 |
| 689 // Draw the top stroke. | 681 // Draw the top stroke. |
| 690 [[NSGraphicsContext currentContext] saveGraphicsState]; | 682 [context saveGraphicsState]; |
| 691 if (selected) { | 683 if (selected) { |
| 692 [[NSColor colorWithDeviceWhite:0.0 alpha:active ? 0.3 : 0.15] set]; | 684 [[NSColor colorWithDeviceWhite:0.0 alpha:active ? 0.3 : 0.15] set]; |
| 693 } else { | 685 } else { |
| 694 [[NSColor colorWithDeviceWhite:0.0 alpha:active ? 0.2 : 0.15] set]; | 686 [[NSColor colorWithDeviceWhite:0.0 alpha:active ? 0.2 : 0.15] set]; |
| 695 [[NSBezierPath bezierPathWithRect:NSOffsetRect(rect, 0, 2.5)] addClip]; | 687 [[NSBezierPath bezierPathWithRect:NSOffsetRect(rect, 0, 2.5)] addClip]; |
| 696 } | 688 } |
| 697 [path setLineWidth:1.0]; | 689 [path setLineWidth:1.0]; |
| 698 [path stroke]; | 690 [path stroke]; |
| 699 [[NSGraphicsContext currentContext] restoreGraphicsState]; | 691 [context restoreGraphicsState]; |
| 700 | 692 |
| 701 // Draw the bottom border. | 693 // Draw the bottom border. |
| 702 if (!selected) { | 694 if (!selected) { |
| 703 [path addClip]; | 695 [path addClip]; |
| 704 NSRect borderRect, contentRect; | 696 NSRect borderRect, contentRect; |
| 705 NSDivideRect(rect, &borderRect, &contentRect, 2.5, NSMinYEdge); | 697 NSDivideRect(rect, &borderRect, &contentRect, 2.5, NSMinYEdge); |
| 706 [[NSColor colorWithDeviceWhite:0.0 alpha:active ? 0.3 : 0.15] set]; | 698 [[NSColor colorWithDeviceWhite:0.0 alpha:active ? 0.3 : 0.15] set]; |
| 707 NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); | 699 NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); |
| 708 } | 700 } |
| 709 [[NSGraphicsContext currentContext] restoreGraphicsState]; | 701 [context restoreGraphicsState]; |
| 710 } | 702 } |
| 711 | 703 |
| 712 // Called when the user hits the right mouse button (or control-clicks) to | 704 // Called when the user hits the right mouse button (or control-clicks) to |
| 713 // show a context menu. | 705 // show a context menu. |
| 714 - (void)rightMouseDown:(NSEvent*)theEvent { | 706 - (void)rightMouseDown:(NSEvent*)theEvent { |
| 715 [NSMenu popUpContextMenu:[self menu] withEvent:theEvent forView:self]; | 707 [NSMenu popUpContextMenu:[self menu] withEvent:theEvent forView:self]; |
| 716 } | 708 } |
| 717 | 709 |
| 710 - (void)viewDidMoveToWindow { |
| 711 [super viewDidMoveToWindow]; |
| 712 if ([self window]) { |
| 713 [controller_ updateTitleColor]; |
| 714 } |
| 715 } |
| 716 |
| 718 @end | 717 @end |
| OLD | NEW |