| 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.h" | 5 #include "chrome/browser/ui/views/tabs/tab.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/debug/alias.h" | 10 #include "base/debug/alias.h" |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 // The minimum opacity (out of 1) when a tab (either active or inactive) is | 122 // The minimum opacity (out of 1) when a tab (either active or inactive) is |
| 123 // throbbing in the immersive mode light strip. | 123 // throbbing in the immersive mode light strip. |
| 124 const double kImmersiveTabMinThrobOpacity = 0.66; | 124 const double kImmersiveTabMinThrobOpacity = 0.66; |
| 125 | 125 |
| 126 // Number of steps in the immersive mode loading animation. | 126 // Number of steps in the immersive mode loading animation. |
| 127 const int kImmersiveLoadingStepCount = 32; | 127 const int kImmersiveLoadingStepCount = 32; |
| 128 | 128 |
| 129 const char kTabCloseButtonName[] = "TabCloseButton"; | 129 const char kTabCloseButtonName[] = "TabCloseButton"; |
| 130 const int kTabCloseButtonSize = 16; | 130 const int kTabCloseButtonSize = 16; |
| 131 | 131 |
| 132 // Returns the width of the tab endcap at scale 1. More precisely, this is the |
| 133 // width of the curve making up either the outer or inner edge of the stroke; |
| 134 // since these two curves are horizontally offset by 1 px (regardless of scale), |
| 135 // the total width of the endcap from tab outer edge to the inside end of the |
| 136 // stroke inner edge is (GetUnscaledEndcapWidth() * scale) + 1. |
| 137 float GetUnscaledEndcapWidth() { |
| 138 return GetLayoutInsets(TAB).left() - 0.5f; |
| 139 } |
| 140 |
| 132 chrome::HostDesktopType GetHostDesktopType(views::View* view) { | 141 chrome::HostDesktopType GetHostDesktopType(views::View* view) { |
| 133 // Widget is NULL when tabs are detached. | 142 // Widget is NULL when tabs are detached. |
| 134 views::Widget* widget = view->GetWidget(); | 143 views::Widget* widget = view->GetWidget(); |
| 135 return chrome::GetHostDesktopTypeForNativeView( | 144 return chrome::GetHostDesktopTypeForNativeView( |
| 136 widget ? widget->GetNativeView() : NULL); | 145 widget ? widget->GetNativeView() : NULL); |
| 137 } | 146 } |
| 138 | 147 |
| 139 // Stop()s |animation| and then deletes it. We do this rather than just deleting | 148 // Stop()s |animation| and then deletes it. We do this rather than just deleting |
| 140 // so that the delegate is notified before the destruction. | 149 // so that the delegate is notified before the destruction. |
| 141 void StopAndDeleteAnimation(scoped_ptr<gfx::Animation> animation) { | 150 void StopAndDeleteAnimation(scoped_ptr<gfx::Animation> animation) { |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 int Tab::GetYInsetForActiveTabBackground() { | 699 int Tab::GetYInsetForActiveTabBackground() { |
| 691 // The computed value here is strangely less than the height of the area atop | 700 // The computed value here is strangely less than the height of the area atop |
| 692 // the tab that doesn't get a background painted; otherwise, we could compute | 701 // the tab that doesn't get a background painted; otherwise, we could compute |
| 693 // the value by simply using GetLayoutInsets(TAB).top(). My suspicion is that | 702 // the value by simply using GetLayoutInsets(TAB).top(). My suspicion is that |
| 694 // originally there was some sort of off-by-one error in how this background | 703 // originally there was some sort of off-by-one error in how this background |
| 695 // was painted, and theme authors compensated; now we're stuck perpetuating it | 704 // was painted, and theme authors compensated; now we're stuck perpetuating it |
| 696 // as a result. | 705 // as a result. |
| 697 return GetLayoutConstant(TAB_TOP_EXCLUSION_HEIGHT) + 1; | 706 return GetLayoutConstant(TAB_TOP_EXCLUSION_HEIGHT) + 1; |
| 698 } | 707 } |
| 699 | 708 |
| 709 // static |
| 710 float Tab::GetInverseDiagonalSlope() { |
| 711 // This is computed from the border path as follows: |
| 712 // * The unscaled endcap width is enough for the whole stroke outer curve, |
| 713 // i.e. the side diagonal plus the curves on both its ends. |
| 714 // * The bottom and top curve are each (2 * scale) px wide, so the diagonal is |
| 715 // (unscaled endcap width - 2 - 2) * scale px wide. |
| 716 // * The bottom and top curve are each 1.5 px high. Additionally, there is an |
| 717 // extra 1 px below the bottom curve and (scale - 1) px above the top curve, |
| 718 // so the diagonal is ((height - 1.5 - 1.5) * scale - 1 - (scale - 1)) px |
| 719 // high. |
| 720 // Simplifying these gives the expression below. |
| 721 return (GetUnscaledEndcapWidth() - 4) / |
| 722 (GetMinimumInactiveSize().height() - 4); |
| 723 } |
| 724 |
| 700 //////////////////////////////////////////////////////////////////////////////// | 725 //////////////////////////////////////////////////////////////////////////////// |
| 701 // Tab, AnimationDelegate overrides: | 726 // Tab, AnimationDelegate overrides: |
| 702 | 727 |
| 703 void Tab::AnimationProgressed(const gfx::Animation* animation) { | 728 void Tab::AnimationProgressed(const gfx::Animation* animation) { |
| 704 // Ignore if the pulse animation is being performed on active tab because | 729 // Ignore if the pulse animation is being performed on active tab because |
| 705 // it repaints the same image. See |Tab::PaintTabBackground()|. | 730 // it repaints the same image. See |Tab::PaintTabBackground()|. |
| 706 if (animation == pulse_animation_.get() && IsActive()) | 731 if (animation == pulse_animation_.get() && IsActive()) |
| 707 return; | 732 return; |
| 708 SchedulePaint(); | 733 SchedulePaint(); |
| 709 } | 734 } |
| (...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1600 // Extends the area to the bottom when the crash animation is in progress. | 1625 // Extends the area to the bottom when the crash animation is in progress. |
| 1601 if (crash_icon_animation_) | 1626 if (crash_icon_animation_) |
| 1602 bounds.set_height(height() - bounds.y()); | 1627 bounds.set_height(height() - bounds.y()); |
| 1603 bounds.set_x(GetMirroredXForRect(bounds)); | 1628 bounds.set_x(GetMirroredXForRect(bounds)); |
| 1604 SchedulePaintInRect(bounds); | 1629 SchedulePaintInRect(bounds); |
| 1605 } | 1630 } |
| 1606 | 1631 |
| 1607 void Tab::GetFillPath(float scale, SkPath* fill) const { | 1632 void Tab::GetFillPath(float scale, SkPath* fill) const { |
| 1608 const float right = width() * scale; | 1633 const float right = width() * scale; |
| 1609 const float bottom = height() * scale; | 1634 const float bottom = height() * scale; |
| 1635 const float unscaled_endcap_width = GetUnscaledEndcapWidth(); |
| 1610 | 1636 |
| 1611 fill->moveTo(right - 1, bottom); | 1637 fill->moveTo(right - 1, bottom); |
| 1612 fill->rCubicTo(-0.75 * scale, 0, -1.625 * scale, -0.5 * scale, -2 * scale, | 1638 fill->rCubicTo(-0.75 * scale, 0, -1.625 * scale, -0.5 * scale, -2 * scale, |
| 1613 -1.5 * scale); | 1639 -1.5 * scale); |
| 1614 fill->lineTo(right - 1 - 13.5 * scale, 2.5 * scale); | 1640 fill->lineTo(right - 1 - (unscaled_endcap_width - 2) * scale, 2.5 * scale); |
| 1615 // Prevent overdraw in the center near minimum width (only happens if | 1641 // Prevent overdraw in the center near minimum width (only happens if |
| 1616 // scale < 2). We could instead avoid this by increasing the tab inset | 1642 // scale < 2). We could instead avoid this by increasing the tab inset |
| 1617 // values, but that would shift all the content inward as well, unless we | 1643 // values, but that would shift all the content inward as well, unless we |
| 1618 // then overlapped the content on the endcaps, by which point we'd have a | 1644 // then overlapped the content on the endcaps, by which point we'd have a |
| 1619 // huge mess. | 1645 // huge mess. |
| 1620 const float total_endcap_width = 31 * scale + 2; | 1646 const float scaled_endcap_width = 1 + unscaled_endcap_width * scale; |
| 1621 const float overlap = total_endcap_width - right; | 1647 const float overlap = scaled_endcap_width * 2 - right; |
| 1622 const float offset = (overlap > 0) ? (overlap / 2) : 0; | 1648 const float offset = (overlap > 0) ? (overlap / 2) : 0; |
| 1623 fill->rCubicTo(-0.375 * scale, -1 * scale, -1.25 * scale + offset, | 1649 fill->rCubicTo(-0.375 * scale, -1 * scale, -1.25 * scale + offset, |
| 1624 -1.5 * scale, -2 * scale + offset, -1.5 * scale); | 1650 -1.5 * scale, -2 * scale + offset, -1.5 * scale); |
| 1625 if (overlap < 0) | 1651 if (overlap < 0) |
| 1626 fill->lineTo(1 + 15.5 * scale, scale); | 1652 fill->lineTo(scaled_endcap_width, scale); |
| 1627 fill->rCubicTo(-0.75 * scale, 0, -1.625 * scale - offset, 0.5 * scale, | 1653 fill->rCubicTo(-0.75 * scale, 0, -1.625 * scale - offset, 0.5 * scale, |
| 1628 -2 * scale - offset, 1.5 * scale); | 1654 -2 * scale - offset, 1.5 * scale); |
| 1629 fill->lineTo(1 + 2 * scale, bottom - 1.5 * scale); | 1655 fill->lineTo(1 + 2 * scale, bottom - 1.5 * scale); |
| 1630 fill->rCubicTo(-0.375 * scale, scale, -1.25 * scale, 1.5 * scale, -2 * scale, | 1656 fill->rCubicTo(-0.375 * scale, scale, -1.25 * scale, 1.5 * scale, -2 * scale, |
| 1631 1.5 * scale); | 1657 1.5 * scale); |
| 1632 fill->close(); | 1658 fill->close(); |
| 1633 } | 1659 } |
| 1634 | 1660 |
| 1635 void Tab::GetBorderPath(float scale, bool extend_to_top, SkPath* path) const { | 1661 void Tab::GetBorderPath(float scale, bool extend_to_top, SkPath* path) const { |
| 1636 const float top = scale - 1; | 1662 const float top = scale - 1; |
| 1637 const float right = width() * scale; | 1663 const float right = width() * scale; |
| 1638 const float bottom = height() * scale; | 1664 const float bottom = height() * scale; |
| 1665 const float unscaled_endcap_width = GetUnscaledEndcapWidth(); |
| 1639 | 1666 |
| 1640 path->moveTo(0, bottom); | 1667 path->moveTo(0, bottom); |
| 1641 path->rLineTo(0, -1); | 1668 path->rLineTo(0, -1); |
| 1642 path->rCubicTo(0.75 * scale, 0, 1.625 * scale, -0.5 * scale, 2 * scale, | 1669 path->rCubicTo(0.75 * scale, 0, 1.625 * scale, -0.5 * scale, 2 * scale, |
| 1643 -1.5 * scale); | 1670 -1.5 * scale); |
| 1644 path->lineTo(13.5 * scale, top + 1.5 * scale); | 1671 path->lineTo((unscaled_endcap_width - 2) * scale, top + 1.5 * scale); |
| 1645 if (extend_to_top) { | 1672 if (extend_to_top) { |
| 1646 // Create the vertical extension by extending the side diagonals until they | 1673 // Create the vertical extension by extending the side diagonals until they |
| 1647 // reach the top of the bounds. | 1674 // reach the top of the bounds. |
| 1648 const float dy = 2.5 * scale - 1; | 1675 const float dy = 2.5 * scale - 1; |
| 1649 const float dx = 11.5 / 25 * dy; | 1676 const float dx = GetInverseDiagonalSlope() * dy; |
| 1650 path->rLineTo(dx, -dy); | 1677 path->rLineTo(dx, -dy); |
| 1651 path->lineTo(right - 13.5 * scale - dx, 0); | 1678 path->lineTo(right - (unscaled_endcap_width - 2) * scale - dx, 0); |
| 1652 path->rLineTo(dx, dy); | 1679 path->rLineTo(dx, dy); |
| 1653 } else { | 1680 } else { |
| 1654 path->rCubicTo(0.375 * scale, -scale, 1.25 * scale, -1.5 * scale, 2 * scale, | 1681 path->rCubicTo(0.375 * scale, -scale, 1.25 * scale, -1.5 * scale, 2 * scale, |
| 1655 -1.5 * scale); | 1682 -1.5 * scale); |
| 1656 path->lineTo(right - 15.5 * scale, top); | 1683 path->lineTo(right - unscaled_endcap_width * scale, top); |
| 1657 path->rCubicTo(0.75 * scale, 0, 1.625 * scale, 0.5 * scale, 2 * scale, | 1684 path->rCubicTo(0.75 * scale, 0, 1.625 * scale, 0.5 * scale, 2 * scale, |
| 1658 1.5 * scale); | 1685 1.5 * scale); |
| 1659 } | 1686 } |
| 1660 path->lineTo(right - 2 * scale, bottom - 1 - 1.5 * scale); | 1687 path->lineTo(right - 2 * scale, bottom - 1 - 1.5 * scale); |
| 1661 path->rCubicTo(0.375 * scale, scale, 1.25 * scale, 1.5 * scale, 2 * scale, | 1688 path->rCubicTo(0.375 * scale, scale, 1.25 * scale, 1.5 * scale, 2 * scale, |
| 1662 1.5 * scale); | 1689 1.5 * scale); |
| 1663 path->rLineTo(0, 1); | 1690 path->rLineTo(0, 1); |
| 1664 path->close(); | 1691 path->close(); |
| 1665 } | 1692 } |
| 1666 | 1693 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1734 const gfx::ImageSkia& image) { | 1761 const gfx::ImageSkia& image) { |
| 1735 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); | 1762 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); |
| 1736 ImageCacheEntry entry; | 1763 ImageCacheEntry entry; |
| 1737 entry.resource_id = resource_id; | 1764 entry.resource_id = resource_id; |
| 1738 entry.scale_factor = scale_factor; | 1765 entry.scale_factor = scale_factor; |
| 1739 entry.image = image; | 1766 entry.image = image; |
| 1740 image_cache_->push_front(entry); | 1767 image_cache_->push_front(entry); |
| 1741 if (image_cache_->size() > kMaxImageCacheSize) | 1768 if (image_cache_->size() > kMaxImageCacheSize) |
| 1742 image_cache_->pop_back(); | 1769 image_cache_->pop_back(); |
| 1743 } | 1770 } |
| OLD | NEW |