OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/ui/cocoa/tabs/tab_view.h" | 5 #import "chrome/browser/ui/cocoa/tabs/tab_view.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "chrome/browser/themes/theme_service.h" | 8 #include "chrome/browser/themes/theme_service.h" |
9 #import "chrome/browser/ui/cocoa/nsview_additions.h" | 9 #import "chrome/browser/ui/cocoa/nsview_additions.h" |
10 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" | 10 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 // If the mouse up occurred in our view or over the close button, then | 244 // If the mouse up occurred in our view or over the close button, then |
245 // close. | 245 // close. |
246 if ([self hitTest:upLocation]) | 246 if ([self hitTest:upLocation]) |
247 [controller_ closeTab:self]; | 247 [controller_ closeTab:self]; |
248 } | 248 } |
249 } | 249 } |
250 | 250 |
251 - (void)drawRect:(NSRect)dirtyRect { | 251 - (void)drawRect:(NSRect)dirtyRect { |
252 const CGFloat lineWidth = [self cr_lineWidth]; | 252 const CGFloat lineWidth = [self cr_lineWidth]; |
253 | 253 |
254 gfx::ScopedNSGraphicsContextSaveGState scopedGState; | |
255 NSGraphicsContext* context = [NSGraphicsContext currentContext]; | 254 NSGraphicsContext* context = [NSGraphicsContext currentContext]; |
| 255 gfx::ScopedNSGraphicsContextSaveGState scopedGState(context); |
256 | 256 |
257 ThemeService* themeProvider = | 257 ThemeService* themeProvider = |
258 static_cast<ThemeService*>([[self window] themeProvider]); | 258 static_cast<ThemeService*>([[self window] themeProvider]); |
259 [context setPatternPhase:[[self window] themePatternPhase]]; | 259 [context setPatternPhase:[[self window] themePatternPhase]]; |
260 | 260 |
261 NSRect rect = [self bounds]; | 261 NSRect rect = [self bounds]; |
262 NSBezierPath* path = [self bezierPathForRect:rect]; | 262 NSBezierPath* path = [self bezierPathForRect:rect]; |
263 | 263 |
264 BOOL selected = [self state]; | 264 BOOL selected = [self state]; |
265 // Don't draw the window/tab bar background when selected, since the tab | 265 // Don't draw the window/tab bar background when selected, since the tab |
(...skipping 15 matching lines...) Expand all Loading... |
281 if (backgroundImageColor) { | 281 if (backgroundImageColor) { |
282 [backgroundImageColor set]; | 282 [backgroundImageColor set]; |
283 [path fill]; | 283 [path fill]; |
284 } else { | 284 } else { |
285 // Use the window's background color rather than |[NSColor | 285 // Use the window's background color rather than |[NSColor |
286 // windowBackgroundColor]|, which gets confused by the fullscreen window. | 286 // windowBackgroundColor]|, which gets confused by the fullscreen window. |
287 // (The result is the same for normal, non-fullscreen windows.) | 287 // (The result is the same for normal, non-fullscreen windows.) |
288 [[[self window] backgroundColor] set]; | 288 [[[self window] backgroundColor] set]; |
289 [path fill]; | 289 [path fill]; |
290 | 290 |
291 gfx::ScopedNSGraphicsContextSaveGState drawBackgroundState; | 291 gfx::ScopedNSGraphicsContextSaveGState drawBackgroundState(context); |
292 NSGraphicsContext* context = [NSGraphicsContext currentContext]; | |
293 CGContextRef cgContext = | 292 CGContextRef cgContext = |
294 static_cast<CGContextRef>([context graphicsPort]); | 293 static_cast<CGContextRef>([context graphicsPort]); |
295 CGContextBeginTransparencyLayer(cgContext, 0); | 294 CGContextBeginTransparencyLayer(cgContext, 0); |
296 CGContextSetAlpha(cgContext, 0.5); | 295 CGContextSetAlpha(cgContext, 0.5); |
297 [path addClip]; | 296 [path addClip]; |
298 [super drawBackgroundWithOpaque:NO]; | 297 [super drawBackgroundWithOpaque:NO]; |
299 CGContextEndTransparencyLayer(cgContext); | 298 CGContextEndTransparencyLayer(cgContext); |
300 } | 299 } |
301 } | 300 } |
302 | 301 |
| 302 [context saveGraphicsState]; |
| 303 [path addClip]; |
| 304 |
| 305 // Use the same overlay for the selected state and for hover and alert glows; |
| 306 // for the selected state, it's fully opaque. |
| 307 CGFloat hoverAlpha = [self hoverAlpha]; |
| 308 CGFloat alertAlpha = [self alertAlpha]; |
| 309 if (selected || hoverAlpha > 0 || alertAlpha > 0) { |
| 310 // Draw the selected background / glow overlay. |
| 311 gfx::ScopedNSGraphicsContextSaveGState drawHoverState(context); |
| 312 CGContextRef cgContext = static_cast<CGContextRef>([context graphicsPort]); |
| 313 CGContextBeginTransparencyLayer(cgContext, 0); |
| 314 if (!selected) { |
| 315 // The alert glow overlay is like the selected state but at most at most |
| 316 // 80% opaque. The hover glow brings up the overlay's opacity at most 50%. |
| 317 CGFloat backgroundAlpha = 0.8 * alertAlpha; |
| 318 backgroundAlpha += (1 - backgroundAlpha) * 0.5 * hoverAlpha; |
| 319 CGContextSetAlpha(cgContext, backgroundAlpha); |
| 320 } |
| 321 [path addClip]; |
| 322 { |
| 323 gfx::ScopedNSGraphicsContextSaveGState drawBackgroundState(context); |
| 324 [super drawBackgroundWithOpaque:NO]; |
| 325 } |
| 326 |
| 327 // Draw a mouse hover gradient for the default themes. |
| 328 if (!selected && hoverAlpha > 0) { |
| 329 if (themeProvider && !hasBackgroundImage) { |
| 330 scoped_nsobject<NSGradient> glow([NSGradient alloc]); |
| 331 [glow initWithStartingColor:[NSColor colorWithCalibratedWhite:1.0 |
| 332 alpha:1.0 * hoverAlpha] |
| 333 endingColor:[NSColor colorWithCalibratedWhite:1.0 |
| 334 alpha:0.0]]; |
| 335 |
| 336 NSPoint point = hoverPoint_; |
| 337 point.y = NSHeight(rect); |
| 338 [glow drawFromCenter:point |
| 339 radius:0.0 |
| 340 toCenter:point |
| 341 radius:NSWidth(rect) / 3.0 |
| 342 options:NSGradientDrawsBeforeStartingLocation]; |
| 343 |
| 344 [glow drawInBezierPath:path relativeCenterPosition:hoverPoint_]; |
| 345 } |
| 346 } |
| 347 |
| 348 CGContextEndTransparencyLayer(cgContext); |
| 349 } |
| 350 |
303 BOOL active = [[self window] isKeyWindow] || [[self window] isMainWindow]; | 351 BOOL active = [[self window] isKeyWindow] || [[self window] isMainWindow]; |
304 CGFloat borderAlpha = selected ? (active ? 0.3 : 0.2) : 0.2; | 352 CGFloat borderAlpha = selected ? (active ? 0.3 : 0.2) : 0.2; |
305 NSColor* borderColor = [NSColor colorWithDeviceWhite:0.0 alpha:borderAlpha]; | 353 NSColor* borderColor = [NSColor colorWithDeviceWhite:0.0 alpha:borderAlpha]; |
306 NSColor* highlightColor = themeProvider ? themeProvider->GetNSColor( | 354 NSColor* highlightColor = themeProvider ? themeProvider->GetNSColor( |
307 themeProvider->UsingDefaultTheme() ? | 355 themeProvider->UsingDefaultTheme() ? |
308 ThemeService::COLOR_TOOLBAR_BEZEL : | 356 ThemeService::COLOR_TOOLBAR_BEZEL : |
309 ThemeService::COLOR_TOOLBAR, true) : nil; | 357 ThemeService::COLOR_TOOLBAR, true) : nil; |
310 | 358 |
311 { | 359 // Draw the top inner highlight within the tab if using the default theme. |
312 gfx::ScopedNSGraphicsContextSaveGState contextSave; | 360 if (themeProvider && themeProvider->UsingDefaultTheme()) { |
313 [path addClip]; | 361 NSAffineTransform* highlightTransform = [NSAffineTransform transform]; |
314 | 362 [highlightTransform translateXBy:lineWidth yBy:-lineWidth]; |
315 // Use the same overlay for the selected state and for hover and alert | 363 if (selected) { |
316 // glows; for the selected state, it's fully opaque. | 364 scoped_nsobject<NSBezierPath> highlightPath([path copy]); |
317 CGFloat hoverAlpha = [self hoverAlpha]; | 365 [highlightPath transformUsingAffineTransform:highlightTransform]; |
318 CGFloat alertAlpha = [self alertAlpha]; | 366 [highlightColor setStroke]; |
319 if (selected || hoverAlpha > 0 || alertAlpha > 0) { | 367 [highlightPath setLineWidth:lineWidth]; |
320 // Draw the selected background / glow overlay. | 368 [highlightPath stroke]; |
321 gfx::ScopedNSGraphicsContextSaveGState drawHoverState; | 369 highlightTransform = [NSAffineTransform transform]; |
322 NSGraphicsContext* context = [NSGraphicsContext currentContext]; | 370 [highlightTransform translateXBy:-2 * lineWidth yBy:0.0]; |
323 CGContextRef cgContext = | 371 [highlightPath transformUsingAffineTransform:highlightTransform]; |
324 static_cast<CGContextRef>([context graphicsPort]); | 372 [highlightPath stroke]; |
325 CGContextBeginTransparencyLayer(cgContext, 0); | 373 } else { |
326 if (!selected) { | 374 NSBezierPath* topHighlightPath = |
327 // The alert glow overlay is like the selected state but at most at most | 375 [self topHighlightBezierPathForRect:[self bounds]]; |
328 // 80% opaque. The hover glow brings up the overlay's opacity at most | 376 [topHighlightPath transformUsingAffineTransform:highlightTransform]; |
329 // 50%. | 377 [highlightColor setStroke]; |
330 CGFloat backgroundAlpha = 0.8 * alertAlpha; | 378 [topHighlightPath setLineWidth:lineWidth]; |
331 backgroundAlpha += (1 - backgroundAlpha) * 0.5 * hoverAlpha; | 379 [topHighlightPath stroke]; |
332 CGContextSetAlpha(cgContext, backgroundAlpha); | |
333 } | |
334 [path addClip]; | |
335 { | |
336 gfx::ScopedNSGraphicsContextSaveGState drawBackgroundState; | |
337 [super drawBackgroundWithOpaque:NO]; | |
338 } | |
339 | |
340 // Draw a mouse hover gradient for the default themes. | |
341 if (!selected && hoverAlpha > 0) { | |
342 if (themeProvider && !hasBackgroundImage) { | |
343 scoped_nsobject<NSGradient> glow([NSGradient alloc]); | |
344 [glow initWithStartingColor:[NSColor colorWithCalibratedWhite:1.0 | |
345 alpha:1.0 * hoverAlpha] | |
346 endingColor:[NSColor colorWithCalibratedWhite:1.0 | |
347 alpha:0.0]]; | |
348 | |
349 NSPoint point = hoverPoint_; | |
350 point.y = NSHeight(rect); | |
351 [glow drawFromCenter:point | |
352 radius:0.0 | |
353 toCenter:point | |
354 radius:NSWidth(rect) / 3.0 | |
355 options:NSGradientDrawsBeforeStartingLocation]; | |
356 | |
357 [glow drawInBezierPath:path relativeCenterPosition:hoverPoint_]; | |
358 } | |
359 } | |
360 | |
361 CGContextEndTransparencyLayer(cgContext); | |
362 } | |
363 | |
364 // Draw the top inner highlight within the tab if using the default theme. | |
365 if (themeProvider && themeProvider->UsingDefaultTheme()) { | |
366 NSAffineTransform* highlightTransform = [NSAffineTransform transform]; | |
367 [highlightTransform translateXBy:lineWidth yBy:-lineWidth]; | |
368 if (selected) { | |
369 scoped_nsobject<NSBezierPath> highlightPath([path copy]); | |
370 [highlightPath transformUsingAffineTransform:highlightTransform]; | |
371 [highlightColor setStroke]; | |
372 [highlightPath setLineWidth:lineWidth]; | |
373 [highlightPath stroke]; | |
374 highlightTransform = [NSAffineTransform transform]; | |
375 [highlightTransform translateXBy:-2 * lineWidth yBy:0.0]; | |
376 [highlightPath transformUsingAffineTransform:highlightTransform]; | |
377 [highlightPath stroke]; | |
378 } else { | |
379 NSBezierPath* topHighlightPath = | |
380 [self topHighlightBezierPathForRect:[self bounds]]; | |
381 [topHighlightPath transformUsingAffineTransform:highlightTransform]; | |
382 [highlightColor setStroke]; | |
383 [topHighlightPath setLineWidth:lineWidth]; | |
384 [topHighlightPath stroke]; | |
385 } | |
386 } | 380 } |
387 } | 381 } |
388 | 382 |
| 383 [context restoreGraphicsState]; |
| 384 |
389 // Draw the top stroke. | 385 // Draw the top stroke. |
390 { | 386 { |
391 gfx::ScopedNSGraphicsContextSaveGState drawBorderState; | 387 gfx::ScopedNSGraphicsContextSaveGState drawBorderState(context); |
392 [borderColor set]; | 388 [borderColor set]; |
393 [path setLineWidth:lineWidth]; | 389 [path setLineWidth:lineWidth]; |
394 [path stroke]; | 390 [path stroke]; |
395 } | 391 } |
396 | 392 |
397 // Mimic the tab strip's bottom border, which consists of a dark border | 393 // Mimic the tab strip's bottom border, which consists of a dark border |
398 // and light highlight. | 394 // and light highlight. |
399 if (![controller_ active]) { | 395 if (![controller_ active]) { |
400 [path addClip]; | 396 [path addClip]; |
401 NSRect borderRect = rect; | 397 NSRect borderRect = rect; |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
651 NSMakePoint(NSMinX(rect) + kInsetMultiplier * NSHeight(rect), | 647 NSMakePoint(NSMinX(rect) + kInsetMultiplier * NSHeight(rect), |
652 NSMaxY(rect)); | 648 NSMaxY(rect)); |
653 | 649 |
654 NSBezierPath* path = [NSBezierPath bezierPath]; | 650 NSBezierPath* path = [NSBezierPath bezierPath]; |
655 [path moveToPoint:topLeft]; | 651 [path moveToPoint:topLeft]; |
656 [path lineToPoint:topRight]; | 652 [path lineToPoint:topRight]; |
657 return path; | 653 return path; |
658 } | 654 } |
659 | 655 |
660 @end // @implementation TabView(Private) | 656 @end // @implementation TabView(Private) |
OLD | NEW |