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 |