Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/views/tabs/tab_strip.h" | 5 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <iterator> | 10 #include <iterator> |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 37 #include "content/public/browser/user_metrics.h" | 37 #include "content/public/browser/user_metrics.h" |
| 38 #include "content/public/common/content_switches.h" | 38 #include "content/public/common/content_switches.h" |
| 39 #include "third_party/skia/include/core/SkColorFilter.h" | 39 #include "third_party/skia/include/core/SkColorFilter.h" |
| 40 #include "third_party/skia/include/effects/SkBlurMaskFilter.h" | 40 #include "third_party/skia/include/effects/SkBlurMaskFilter.h" |
| 41 #include "third_party/skia/include/effects/SkLayerDrawLooper.h" | 41 #include "third_party/skia/include/effects/SkLayerDrawLooper.h" |
| 42 #include "third_party/skia/include/pathops/SkPathOps.h" | 42 #include "third_party/skia/include/pathops/SkPathOps.h" |
| 43 #include "ui/accessibility/ax_view_state.h" | 43 #include "ui/accessibility/ax_view_state.h" |
| 44 #include "ui/base/default_theme_provider.h" | 44 #include "ui/base/default_theme_provider.h" |
| 45 #include "ui/base/dragdrop/drag_drop_types.h" | 45 #include "ui/base/dragdrop/drag_drop_types.h" |
| 46 #include "ui/base/l10n/l10n_util.h" | 46 #include "ui/base/l10n/l10n_util.h" |
| 47 #include "ui/base/material_design/material_design_controller.h" | |
| 48 #include "ui/base/models/list_selection_model.h" | 47 #include "ui/base/models/list_selection_model.h" |
| 49 #include "ui/base/resource/resource_bundle.h" | 48 #include "ui/base/resource/resource_bundle.h" |
| 50 #include "ui/compositor/compositing_recorder.h" | 49 #include "ui/compositor/compositing_recorder.h" |
| 51 #include "ui/compositor/paint_recorder.h" | 50 #include "ui/compositor/paint_recorder.h" |
| 52 #include "ui/display/display.h" | 51 #include "ui/display/display.h" |
| 53 #include "ui/display/screen.h" | 52 #include "ui/display/screen.h" |
| 54 #include "ui/gfx/animation/animation_container.h" | 53 #include "ui/gfx/animation/animation_container.h" |
| 55 #include "ui/gfx/animation/throb_animation.h" | 54 #include "ui/gfx/animation/throb_animation.h" |
| 56 #include "ui/gfx/canvas.h" | 55 #include "ui/gfx/canvas.h" |
| 57 #include "ui/gfx/geometry/rect_conversions.h" | 56 #include "ui/gfx/geometry/rect_conversions.h" |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 } | 361 } |
| 363 | 362 |
| 364 void NewTabButton::OnPaint(gfx::Canvas* canvas) { | 363 void NewTabButton::OnPaint(gfx::Canvas* canvas) { |
| 365 gfx::ScopedCanvas scoped_canvas(canvas); | 364 gfx::ScopedCanvas scoped_canvas(canvas); |
| 366 const int visible_height = GetLayoutSize(NEW_TAB_BUTTON).height(); | 365 const int visible_height = GetLayoutSize(NEW_TAB_BUTTON).height(); |
| 367 canvas->Translate(gfx::Vector2d(0, height() - visible_height)); | 366 canvas->Translate(gfx::Vector2d(0, height() - visible_height)); |
| 368 | 367 |
| 369 const bool pressed = state() == views::CustomButton::STATE_PRESSED; | 368 const bool pressed = state() == views::CustomButton::STATE_PRESSED; |
| 370 const float scale = canvas->image_scale(); | 369 const float scale = canvas->image_scale(); |
| 371 | 370 |
| 371 // Fill. | |
| 372 SkPath fill; | 372 SkPath fill; |
| 373 const ui::ThemeProvider* tp = GetThemeProvider(); | 373 const float fill_bottom = (visible_height - 2) * scale; |
| 374 if (ui::MaterialDesignController::IsModeMaterial()) { | 374 const float diag_height = fill_bottom - 3.5 * scale; |
| 375 // Fill. | 375 const float diag_width = diag_height * Tab::GetInverseDiagonalSlope(); |
| 376 const float fill_bottom = (visible_height - 2) * scale; | 376 fill.moveTo(diag_width + 4 * scale, fill_bottom); |
| 377 const float diag_height = fill_bottom - 3.5 * scale; | 377 fill.rCubicTo(-0.75 * scale, 0, -1.625 * scale, -0.5 * scale, -2 * scale, |
| 378 const float diag_width = diag_height * Tab::GetInverseDiagonalSlope(); | 378 -1.5 * scale); |
| 379 fill.moveTo(diag_width + 4 * scale, fill_bottom); | 379 fill.rLineTo(-diag_width, -diag_height); |
| 380 fill.rCubicTo(-0.75 * scale, 0, -1.625 * scale, -0.5 * scale, -2 * scale, | 380 fill.rCubicTo(0, -0.5 * scale, 0.25 * scale, -scale, scale, -scale); |
| 381 -1.5 * scale); | 381 fill.lineTo((width() - 4) * scale - diag_width, scale); |
| 382 fill.rLineTo(-diag_width, -diag_height); | 382 fill.rCubicTo(0.75 * scale, 0, 1.625 * scale, 0.5 * scale, 2 * scale, |
| 383 fill.rCubicTo(0, -0.5 * scale, 0.25 * scale, -scale, scale, -scale); | 383 1.5 * scale); |
| 384 fill.lineTo((width() - 4) * scale - diag_width, scale); | 384 fill.rLineTo(diag_width, diag_height); |
| 385 fill.rCubicTo(0.75 * scale, 0, 1.625 * scale, 0.5 * scale, 2 * scale, | 385 fill.rCubicTo(0, 0.5 * scale, -0.25 * scale, scale, -scale, scale); |
| 386 1.5 * scale); | 386 fill.close(); |
| 387 fill.rLineTo(diag_width, diag_height); | 387 PaintFill(pressed, scale, fill, canvas); |
| 388 fill.rCubicTo(0, 0.5 * scale, -0.25 * scale, scale, -scale, scale); | |
| 389 fill.close(); | |
| 390 PaintFill(pressed, scale, fill, canvas); | |
| 391 | 388 |
| 392 // Stroke. | 389 // Stroke. |
| 393 gfx::ScopedCanvas scoped_canvas(canvas); | 390 canvas->UndoDeviceScaleFactor(); |
| 394 canvas->UndoDeviceScaleFactor(); | 391 SkPath stroke; |
| 395 SkPath stroke; | 392 GetBorderPath(0, scale, false, &stroke); |
| 396 GetBorderPath(0, scale, false, &stroke); | 393 // We want to draw a drop shadow either inside or outside the stroke, |
| 397 // We want to draw a drop shadow either inside or outside the stroke, | 394 // depending on whether we're pressed; so, either clip out what's outside |
| 398 // depending on whether we're pressed; so, either clip out what's outside | 395 // the stroke, or clip out the fill inside it. |
| 399 // the stroke, or clip out the fill inside it. | 396 if (pressed) |
| 400 if (pressed) | 397 canvas->ClipPath(stroke, true); |
| 401 canvas->ClipPath(stroke, true); | 398 Op(stroke, fill, kDifference_SkPathOp, &stroke); |
| 402 Op(stroke, fill, kDifference_SkPathOp, &stroke); | 399 if (!pressed) |
| 403 if (!pressed) | 400 canvas->sk_canvas()->clipPath(fill, SkRegion::kDifference_Op, true); |
| 404 canvas->sk_canvas()->clipPath(fill, SkRegion::kDifference_Op, true); | 401 // Now draw the stroke and shadow; the stroke will always be visible, while |
| 405 // Now draw the stroke and shadow; the stroke will always be visible, while | 402 // the shadow will be affected by the clip we set above. |
| 406 // the shadow will be affected by the clip we set above. | 403 SkPaint paint; |
| 407 SkPaint paint; | 404 paint.setAntiAlias(true); |
| 408 paint.setAntiAlias(true); | 405 const SkColor stroke_color = tab_strip_->GetToolbarTopSeparatorColor(); |
| 409 const SkColor stroke_color = tab_strip_->GetToolbarTopSeparatorColor(); | 406 const float alpha = SkColorGetA(stroke_color); |
| 410 const float alpha = SkColorGetA(stroke_color); | 407 const SkAlpha shadow_alpha = |
| 411 const SkAlpha shadow_alpha = | 408 base::saturated_cast<SkAlpha>(std::round(2.1875f * alpha)); |
| 412 base::saturated_cast<SkAlpha>(std::round(2.1875f * alpha)); | 409 paint.setLooper( |
| 413 paint.setLooper( | 410 CreateShadowDrawLooper(SkColorSetA(stroke_color, shadow_alpha))); |
| 414 CreateShadowDrawLooper(SkColorSetA(stroke_color, shadow_alpha))); | 411 const SkAlpha path_alpha = static_cast<SkAlpha>( |
| 415 const SkAlpha path_alpha = static_cast<SkAlpha>( | 412 std::round((pressed ? 0.875f : 0.609375f) * alpha)); |
| 416 std::round((pressed ? 0.875f : 0.609375f) * alpha)); | 413 paint.setColor(SkColorSetA(stroke_color, path_alpha)); |
| 417 paint.setColor(SkColorSetA(stroke_color, path_alpha)); | 414 canvas->DrawPath(stroke, paint); |
| 418 canvas->DrawPath(stroke, paint); | |
| 419 } else { | |
| 420 // Fill. | |
| 421 gfx::ImageSkia* mask = tp->GetImageSkiaNamed(IDR_NEWTAB_BUTTON_MASK); | |
| 422 // The canvas and mask have to use the same scale factor. | |
| 423 const float fill_canvas_scale = mask->HasRepresentation(scale) ? | |
| 424 scale : ui::GetScaleForScaleFactor(ui::SCALE_FACTOR_100P); | |
| 425 gfx::Canvas fill_canvas(GetLayoutSize(NEW_TAB_BUTTON), fill_canvas_scale, | |
| 426 false); | |
| 427 PaintFill(pressed, fill_canvas_scale, fill, &fill_canvas); | |
| 428 gfx::ImageSkia image(fill_canvas.ExtractImageRep()); | |
| 429 canvas->DrawImageInt( | |
| 430 gfx::ImageSkiaOperations::CreateMaskedImage(image, *mask), 0, 0); | |
| 431 | |
| 432 // Stroke. Draw the button border with a slight alpha. | |
| 433 static const SkAlpha kGlassFrameOverlayAlpha = 178; | |
| 434 static const SkAlpha kOpaqueFrameOverlayAlpha = 230; | |
| 435 const SkAlpha alpha = GetWidget()->ShouldWindowContentsBeTransparent() ? | |
| 436 kGlassFrameOverlayAlpha : kOpaqueFrameOverlayAlpha; | |
| 437 const int overlay_id = pressed ? IDR_NEWTAB_BUTTON_P : IDR_NEWTAB_BUTTON; | |
| 438 canvas->DrawImageInt(*tp->GetImageSkiaNamed(overlay_id), 0, 0, alpha); | |
| 439 } | |
| 440 } | 415 } |
| 441 | 416 |
| 442 bool NewTabButton::GetHitTestMask(gfx::Path* mask) const { | 417 bool NewTabButton::GetHitTestMask(gfx::Path* mask) const { |
| 443 DCHECK(mask); | 418 DCHECK(mask); |
| 444 | 419 |
| 445 if (ui::MaterialDesignController::IsModeMaterial()) { | 420 SkPath border; |
| 446 SkPath border; | 421 const float scale = GetWidget()->GetCompositor()->device_scale_factor(); |
| 447 const float scale = GetWidget()->GetCompositor()->device_scale_factor(); | 422 GetBorderPath(GetNewTabButtonTopOffset() * scale, scale, |
| 448 GetBorderPath(GetNewTabButtonTopOffset() * scale, scale, | 423 tab_strip_->SizeTabButtonToTopOfTabStrip(), &border); |
| 449 tab_strip_->SizeTabButtonToTopOfTabStrip(), &border); | 424 mask->addPath(border, SkMatrix::MakeScale(1 / scale)); |
| 450 mask->addPath(border, SkMatrix::MakeScale(1 / scale)); | |
| 451 } else if (tab_strip_->SizeTabButtonToTopOfTabStrip()) { | |
| 452 // When the button is sized to the top of the tab strip, we want the hit | |
| 453 // test mask to be defined as the complete (rectangular) bounds of the | |
| 454 // button. | |
| 455 gfx::Rect button_bounds(GetContentsBounds()); | |
| 456 button_bounds.set_x(GetMirroredXForRect(button_bounds)); | |
| 457 mask->addRect(RectToSkRect(button_bounds)); | |
| 458 } else { | |
| 459 SkScalar w = SkIntToScalar(width()); | |
| 460 SkScalar v_offset = SkIntToScalar(GetNewTabButtonTopOffset()); | |
| 461 | |
| 462 // These values are defined by the shape of the new tab image. Should that | |
| 463 // image ever change, these values will need to be updated. They're so | |
| 464 // custom it's not really worth defining constants for. | |
| 465 // These values are correct for regular and USE_ASH versions of the image. | |
| 466 mask->moveTo(0, v_offset + 1); | |
| 467 mask->lineTo(w - 7, v_offset + 1); | |
| 468 mask->lineTo(w - 4, v_offset + 4); | |
| 469 mask->lineTo(w, v_offset + 16); | |
| 470 mask->lineTo(w - 1, v_offset + 17); | |
| 471 mask->lineTo(7, v_offset + 17); | |
| 472 mask->lineTo(4, v_offset + 13); | |
| 473 mask->lineTo(0, v_offset + 1); | |
| 474 mask->close(); | |
| 475 } | |
| 476 | |
| 477 return true; | 425 return true; |
| 478 } | 426 } |
| 479 | 427 |
| 480 void NewTabButton::GetBorderPath(float button_y, | 428 void NewTabButton::GetBorderPath(float button_y, |
| 481 float scale, | 429 float scale, |
| 482 bool extend_to_top, | 430 bool extend_to_top, |
| 483 SkPath* path) const { | 431 SkPath* path) const { |
| 484 const float inverse_slope = Tab::GetInverseDiagonalSlope(); | 432 const float inverse_slope = Tab::GetInverseDiagonalSlope(); |
| 485 const float fill_bottom = | 433 const float fill_bottom = |
| 486 (GetLayoutSize(NEW_TAB_BUTTON).height() - 2) * scale; | 434 (GetLayoutSize(NEW_TAB_BUTTON).height() - 2) * scale; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 513 path->rCubicTo(0.5 * scale, 1.125 * scale, -0.5 * scale, scale + 2, -scale, | 461 path->rCubicTo(0.5 * scale, 1.125 * scale, -0.5 * scale, scale + 2, -scale, |
| 514 scale + 2); | 462 scale + 2); |
| 515 } | 463 } |
| 516 path->close(); | 464 path->close(); |
| 517 } | 465 } |
| 518 | 466 |
| 519 void NewTabButton::PaintFill(bool pressed, | 467 void NewTabButton::PaintFill(bool pressed, |
| 520 float scale, | 468 float scale, |
| 521 const SkPath& fill, | 469 const SkPath& fill, |
| 522 gfx::Canvas* canvas) const { | 470 gfx::Canvas* canvas) const { |
| 523 // First we compute the background image coordinates and scale, in case we | 471 gfx::ScopedCanvas scoped_canvas(canvas); |
| 524 // need to draw a custom background image. | 472 canvas->UndoDeviceScaleFactor(); |
| 525 const ui::ThemeProvider* tp = GetThemeProvider(); | 473 SkPaint paint; |
| 526 bool custom_image; | 474 paint.setAntiAlias(true); |
| 527 const int bg_id = tab_strip_->GetBackgroundResourceId(&custom_image); | 475 |
| 528 // For custom tab backgrounds the background starts at the top of the tab | 476 // For unpressed buttons, draw the fill and its shadow. |
| 529 // strip. Otherwise the background starts at the top of the frame. | 477 if (!pressed) { |
| 530 const int offset_y = tp->HasCustomImage(bg_id) ? 0 : background_offset_.y(); | 478 // First we compute the background image coordinates and scale, in case we |
| 531 // The new tab background is mirrored in RTL mode, but the theme background | 479 // need to draw a custom background image. |
| 532 // should never be mirrored. Mirror it here to compensate. | 480 const ui::ThemeProvider* tp = GetThemeProvider(); |
| 533 float x_scale = 1.0f; | 481 bool custom_image; |
| 534 int x = GetMirroredX() + background_offset_.x(); | 482 const int bg_id = tab_strip_->GetBackgroundResourceId(&custom_image); |
| 535 const gfx::Size size(GetLayoutSize(NEW_TAB_BUTTON)); | 483 if (custom_image) { |
| 536 if (base::i18n::IsRTL()) { | 484 // For custom tab backgrounds the background starts at the top of the tab |
| 537 x_scale = -1.0f; | 485 // strip. Otherwise the background starts at the top of the frame. |
| 538 // Offset by |width| such that the same region is painted as if there was no | 486 const int offset_y = |
| 539 // flip. | 487 tp->HasCustomImage(bg_id) ? 0 : background_offset_.y(); |
| 540 x += size.width(); | 488 // The new tab background is mirrored in RTL mode, but the theme |
| 489 // background should never be mirrored. Mirror it here to compensate. | |
| 490 float x_scale = 1.0f; | |
| 491 int x = GetMirroredX() + background_offset_.x(); | |
| 492 const gfx::Size size(GetLayoutSize(NEW_TAB_BUTTON)); | |
| 493 if (base::i18n::IsRTL()) { | |
| 494 x_scale = -1.0f; | |
| 495 // Offset by |width| such that the same region is painted as if there | |
| 496 // was no flip. | |
| 497 x += size.width(); | |
| 498 } | |
| 499 | |
| 500 const bool succeeded = | |
| 501 canvas->InitSkPaintForTiling(*tp->GetImageSkiaNamed(bg_id), x, | |
| 502 GetNewTabButtonTopOffset() + offset_y, | |
| 503 x_scale * scale, scale, 0, 0, &paint); | |
| 504 DCHECK(succeeded); | |
| 505 } else { | |
| 506 paint.setColor(tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB)); | |
| 507 } | |
| 508 const SkColor stroke_color = tab_strip_->GetToolbarTopSeparatorColor(); | |
| 509 const SkAlpha alpha = static_cast<SkAlpha>( | |
| 510 std::round(SkColorGetA(stroke_color) * 0.59375f)); | |
| 511 SkPaint shadow_paint = paint; | |
| 512 shadow_paint.setLooper( | |
| 513 CreateShadowDrawLooper(SkColorSetA(stroke_color, alpha))); | |
| 514 canvas->DrawPath(fill, shadow_paint); | |
| 541 } | 515 } |
| 542 const int y = GetNewTabButtonTopOffset() + offset_y; | |
| 543 | 516 |
| 544 if (ui::MaterialDesignController::IsModeMaterial()) { | 517 // Draw a white highlight on hover. |
| 545 gfx::ScopedCanvas scoped_canvas(canvas); | 518 const SkAlpha hover_alpha = static_cast<SkAlpha>( |
| 546 canvas->UndoDeviceScaleFactor(); | 519 hover_animation().CurrentValueBetween(0x00, 0x4D)); |
| 520 if (hover_alpha != SK_AlphaTRANSPARENT) { | |
| 521 paint.setColor(SkColorSetA(SK_ColorWHITE, hover_alpha)); | |
| 522 canvas->DrawPath(fill, paint); | |
| 523 } | |
| 547 | 524 |
| 548 // For unpressed buttons, draw the fill and its shadow. | 525 // Most states' opacities are adjusted using an opacity recorder in |
| 549 if (!pressed) { | 526 // TabStrip::PaintChildren(), but the pressed state is excluded there and |
| 550 SkPaint paint; | 527 // instead rendered using a dark overlay here. Avoiding the use of the |
| 551 paint.setAntiAlias(true); | 528 // opacity recorder keeps the stroke more visible in this state. |
| 552 if (custom_image) { | 529 if (pressed) { |
| 553 const bool succeeded = canvas->InitSkPaintForTiling( | 530 paint.setColor(SkColorSetA(SK_ColorBLACK, 0x14)); |
| 554 *tp->GetImageSkiaNamed(bg_id), x, y, x_scale * scale, scale, 0, 0, | 531 canvas->DrawPath(fill, paint); |
| 555 &paint); | |
| 556 DCHECK(succeeded); | |
| 557 } else { | |
| 558 paint.setColor(tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB)); | |
| 559 } | |
| 560 const SkColor stroke_color = tab_strip_->GetToolbarTopSeparatorColor(); | |
| 561 const SkAlpha alpha = static_cast<SkAlpha>( | |
| 562 std::round(SkColorGetA(stroke_color) * 0.59375f)); | |
| 563 paint.setLooper( | |
| 564 CreateShadowDrawLooper(SkColorSetA(stroke_color, alpha))); | |
| 565 canvas->DrawPath(fill, paint); | |
| 566 } | |
| 567 | |
| 568 // Draw a white highlight on hover. | |
| 569 SkPaint paint; | |
| 570 paint.setAntiAlias(true); | |
| 571 const SkAlpha hover_alpha = static_cast<SkAlpha>( | |
| 572 hover_animation().CurrentValueBetween(0x00, 0x4D)); | |
| 573 if (hover_alpha != SK_AlphaTRANSPARENT) { | |
| 574 paint.setColor(SkColorSetA(SK_ColorWHITE, hover_alpha)); | |
| 575 canvas->DrawPath(fill, paint); | |
| 576 } | |
| 577 | |
| 578 // Most states' opacities are adjusted using an opacity recorder in | |
| 579 // TabStrip::PaintChildren(), but the pressed state is excluded there and | |
| 580 // instead rendered using a dark overlay here. This produces a different | |
| 581 // effect than for non-MD, and avoiding the use of the opacity recorder | |
| 582 // keeps the stroke more visible in this state. | |
| 583 if (pressed) { | |
| 584 paint.setColor(SkColorSetA(SK_ColorBLACK, 0x14)); | |
| 585 canvas->DrawPath(fill, paint); | |
| 586 } | |
| 587 } else { | |
| 588 // Draw the fill image. | |
| 589 canvas->TileImageInt(*tp->GetImageSkiaNamed(bg_id), x, y, x_scale, 1.0f, | |
| 590 0, 0, size.width(), size.height()); | |
| 591 | |
| 592 // Adjust the alpha of the fill to match that of inactive tabs (except for | |
| 593 // pressed buttons, which get a different value). For MD, we do this with | |
| 594 // an opacity recorder in TabStrip::PaintChildren() so the fill and stroke | |
| 595 // are both affected, to better match how tabs are handled, but in non-MD, | |
| 596 // the button stroke is already lighter than the tab stroke, and using the | |
| 597 // opacity recorder washes it out too much. | |
| 598 static const SkAlpha kPressedAlpha = 145; | |
| 599 const SkAlpha fill_alpha = | |
| 600 pressed ? kPressedAlpha : tab_strip_->GetInactiveAlpha(true); | |
| 601 if (fill_alpha != 255) { | |
| 602 SkPaint paint; | |
| 603 paint.setAlpha(fill_alpha); | |
| 604 paint.setXfermodeMode(SkXfermode::kDstIn_Mode); | |
| 605 paint.setStyle(SkPaint::kFill_Style); | |
| 606 canvas->DrawRect(gfx::Rect(size), paint); | |
| 607 } | |
| 608 | |
| 609 // Draw a white highlight on hover. | |
| 610 const SkAlpha hover_alpha = static_cast<SkAlpha>( | |
| 611 hover_animation().CurrentValueBetween(0x00, 0x40)); | |
| 612 if (hover_alpha != SK_AlphaTRANSPARENT) { | |
| 613 canvas->FillRect(GetLocalBounds(), | |
| 614 SkColorSetA(SK_ColorWHITE, hover_alpha)); | |
| 615 } | |
| 616 } | 532 } |
| 617 } | 533 } |
| 618 | 534 |
| 619 /////////////////////////////////////////////////////////////////////////////// | 535 /////////////////////////////////////////////////////////////////////////////// |
| 620 // TabStrip::RemoveTabDelegate | 536 // TabStrip::RemoveTabDelegate |
| 621 // | 537 // |
| 622 // AnimationDelegate used when removing a tab. Does the necessary cleanup when | 538 // AnimationDelegate used when removing a tab. Does the necessary cleanup when |
| 623 // done. | 539 // done. |
| 624 class TabStrip::RemoveTabDelegate : public TabAnimationDelegate { | 540 class TabStrip::RemoveTabDelegate : public TabAnimationDelegate { |
| 625 public: | 541 public: |
| (...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1519 // Now selected but not active. We don't want these dimmed if using native | 1435 // Now selected but not active. We don't want these dimmed if using native |
| 1520 // frame, so they're painted after initial pass. | 1436 // frame, so they're painted after initial pass. |
| 1521 for (size_t i = 0; i < selected_tabs.size(); ++i) | 1437 for (size_t i = 0; i < selected_tabs.size(); ++i) |
| 1522 selected_tabs[i]->Paint(context); | 1438 selected_tabs[i]->Paint(context); |
| 1523 | 1439 |
| 1524 // Next comes the active tab. | 1440 // Next comes the active tab. |
| 1525 if (active_tab && !is_dragging) | 1441 if (active_tab && !is_dragging) |
| 1526 active_tab->Paint(context); | 1442 active_tab->Paint(context); |
| 1527 | 1443 |
| 1528 // Paint the New Tab button. | 1444 // Paint the New Tab button. |
| 1529 const bool md = ui::MaterialDesignController::IsModeMaterial(); | 1445 if (newtab_button_->state() != views::CustomButton::STATE_PRESSED) { |
| 1530 if (md && (newtab_button_->state() != views::CustomButton::STATE_PRESSED)) { | |
| 1531 // Match the inactive tab opacity for non-pressed states. See comments in | 1446 // Match the inactive tab opacity for non-pressed states. See comments in |
| 1532 // NewTabButton::PaintFill() for why we don't do this for the pressed state. | 1447 // NewTabButton::PaintFill() for why we don't do this for the pressed state. |
| 1533 // This call doesn't need to set |lcd_text_requires_opaque_layer| to false | 1448 // This call doesn't need to set |lcd_text_requires_opaque_layer| to false |
| 1534 // because no text will be drawn. | 1449 // because no text will be drawn. |
| 1535 ui::CompositingRecorder opacity_recorder(context, GetInactiveAlpha(true), | 1450 ui::CompositingRecorder opacity_recorder(context, GetInactiveAlpha(true), |
| 1536 true); | 1451 true); |
| 1537 newtab_button_->Paint(context); | 1452 newtab_button_->Paint(context); |
| 1538 } else { | |
| 1539 newtab_button_->Paint(context); | |
|
Evan Stade
2016/10/10 19:03:01
oops, should not have removed this clause.
Fix he
| |
| 1540 } | 1453 } |
| 1541 | 1454 |
| 1542 // And the dragged tabs. | 1455 // And the dragged tabs. |
| 1543 for (size_t i = 0; i < tabs_dragging.size(); ++i) | 1456 for (size_t i = 0; i < tabs_dragging.size(); ++i) |
| 1544 tabs_dragging[i]->Paint(context); | 1457 tabs_dragging[i]->Paint(context); |
| 1545 | 1458 |
| 1546 // If the active tab is being dragged, it goes last. | 1459 // If the active tab is being dragged, it goes last. |
| 1547 if (active_tab && is_dragging) | 1460 if (active_tab && is_dragging) |
| 1548 active_tab->Paint(context); | 1461 active_tab->Paint(context); |
| 1549 | 1462 |
| 1550 if (md) { | 1463 ui::PaintRecorder recorder(context, size()); |
| 1551 ui::PaintRecorder recorder(context, size()); | 1464 gfx::Canvas* canvas = recorder.canvas(); |
| 1552 gfx::Canvas* canvas = recorder.canvas(); | 1465 if (active_tab) { |
| 1553 if (active_tab) { | 1466 canvas->sk_canvas()->clipRect( |
| 1554 canvas->sk_canvas()->clipRect( | 1467 gfx::RectToSkRect(active_tab->GetMirroredBounds()), |
| 1555 gfx::RectToSkRect(active_tab->GetMirroredBounds()), | 1468 SkRegion::kDifference_Op); |
| 1556 SkRegion::kDifference_Op); | |
| 1557 } | |
| 1558 BrowserView::Paint1pxHorizontalLine(canvas, GetToolbarTopSeparatorColor(), | |
| 1559 GetLocalBounds(), true); | |
| 1560 } | 1469 } |
| 1470 BrowserView::Paint1pxHorizontalLine(canvas, GetToolbarTopSeparatorColor(), | |
| 1471 GetLocalBounds(), true); | |
| 1561 } | 1472 } |
| 1562 | 1473 |
| 1563 const char* TabStrip::GetClassName() const { | 1474 const char* TabStrip::GetClassName() const { |
| 1564 static const char kViewClassName[] = "TabStrip"; | 1475 static const char kViewClassName[] = "TabStrip"; |
| 1565 return kViewClassName; | 1476 return kViewClassName; |
| 1566 } | 1477 } |
| 1567 | 1478 |
| 1568 gfx::Size TabStrip::GetPreferredSize() const { | 1479 gfx::Size TabStrip::GetPreferredSize() const { |
| 1569 int needed_tab_width; | 1480 int needed_tab_width; |
| 1570 if (touch_layout_ || adjust_layout_) { | 1481 if (touch_layout_ || adjust_layout_) { |
| (...skipping 1317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2888 ConvertPointToViewAndGetEventHandler(this, newtab_button_, point); | 2799 ConvertPointToViewAndGetEventHandler(this, newtab_button_, point); |
| 2889 if (view) | 2800 if (view) |
| 2890 return view; | 2801 return view; |
| 2891 } | 2802 } |
| 2892 Tab* tab = FindTabForEvent(point); | 2803 Tab* tab = FindTabForEvent(point); |
| 2893 if (tab) | 2804 if (tab) |
| 2894 return ConvertPointToViewAndGetEventHandler(this, tab, point); | 2805 return ConvertPointToViewAndGetEventHandler(this, tab, point); |
| 2895 } | 2806 } |
| 2896 return this; | 2807 return this; |
| 2897 } | 2808 } |
| OLD | NEW |