Roll src/third_party/WebKit f36d5e0:68b67cd (svn 193299:193303)
[chromium-blink-merge.git] / components / infobars / core / infobar.cc
blob6e7aca747b94555f068501b295c64eb1a68af59b
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/infobars/core/infobar.h"
7 #include <cmath>
9 #include "base/logging.h"
10 #include "build/build_config.h"
11 #include "components/infobars/core/infobar_container.h"
12 #include "components/infobars/core/infobar_manager.h"
13 #include "ui/gfx/animation/slide_animation.h"
15 namespace infobars {
17 InfoBar::InfoBar(scoped_ptr<InfoBarDelegate> delegate)
18 : owner_(NULL),
19 delegate_(delegate.Pass()),
20 container_(NULL),
21 animation_(this),
22 arrow_height_(0),
23 arrow_target_height_(0),
24 arrow_half_width_(0),
25 bar_height_(0),
26 bar_target_height_(-1) {
27 DCHECK(delegate_ != NULL);
28 animation_.SetTweenType(gfx::Tween::LINEAR);
29 delegate_->set_infobar(this);
32 InfoBar::~InfoBar() {
33 DCHECK(!owner_);
36 // static
37 SkColor InfoBar::GetTopColor(InfoBarDelegate::Type infobar_type) {
38 static const SkColor kWarningBackgroundColorTop =
39 SkColorSetRGB(255, 242, 183); // Yellow
40 static const SkColor kPageActionBackgroundColorTop =
41 SkColorSetRGB(237, 237, 237); // Gray
42 return (infobar_type == InfoBarDelegate::WARNING_TYPE) ?
43 kWarningBackgroundColorTop : kPageActionBackgroundColorTop;
46 // static
47 SkColor InfoBar::GetBottomColor(InfoBarDelegate::Type infobar_type) {
48 static const SkColor kWarningBackgroundColorBottom =
49 SkColorSetRGB(250, 230, 145); // Yellow
50 static const SkColor kPageActionBackgroundColorBottom =
51 SkColorSetRGB(217, 217, 217); // Gray
52 return (infobar_type == InfoBarDelegate::WARNING_TYPE) ?
53 kWarningBackgroundColorBottom : kPageActionBackgroundColorBottom;
56 void InfoBar::SetOwner(InfoBarManager* owner) {
57 DCHECK(!owner_);
58 owner_ = owner;
59 delegate_->StoreActiveEntryUniqueID();
60 PlatformSpecificSetOwner();
63 void InfoBar::Show(bool animate) {
64 PlatformSpecificShow(animate);
65 if (animate) {
66 animation_.Show();
67 } else {
68 animation_.Reset(1.0);
69 RecalculateHeights(true);
73 void InfoBar::Hide(bool animate) {
74 PlatformSpecificHide(animate);
75 if (animate) {
76 animation_.Hide();
77 } else {
78 animation_.Reset(0.0);
79 // We want to remove ourselves from the container immediately even if we
80 // still have an owner, which MaybeDelete() won't do.
81 DCHECK(container_);
82 container_->RemoveInfoBar(this);
83 MaybeDelete(); // Necessary if the infobar was already closing.
87 void InfoBar::SetArrowTargetHeight(int height) {
88 // Once the closing animation starts, we ignore further requests to change the
89 // target height.
90 if ((arrow_target_height_ != height) && !animation_.IsClosing()) {
91 arrow_target_height_ = height;
92 RecalculateHeights(false);
96 void InfoBar::CloseSoon() {
97 owner_ = NULL;
98 PlatformSpecificOnCloseSoon();
99 MaybeDelete();
102 void InfoBar::RemoveSelf() {
103 if (owner_)
104 owner_->RemoveInfoBar(this);
107 void InfoBar::SetBarTargetHeight(int height) {
108 if (bar_target_height_ != height) {
109 bar_target_height_ = height;
110 RecalculateHeights(false);
114 void InfoBar::AnimationProgressed(const gfx::Animation* animation) {
115 RecalculateHeights(false);
118 void InfoBar::AnimationEnded(const gfx::Animation* animation) {
119 // When the animation ends, we must ensure the container is notified even if
120 // the heights haven't changed, lest it never get an "animation finished"
121 // notification. (If the browser doesn't get this notification, it will not
122 // bother to re-layout the content area for the new infobar size.)
123 RecalculateHeights(true);
124 MaybeDelete();
127 void InfoBar::RecalculateHeights(bool force_notify) {
128 // If there's no container delegate, there's no way to compute new element
129 // sizes, so return immediately. We don't need to worry that this might leave
130 // us with bogus sizes, because if we're ever re-added to a container, it will
131 // call Show(false) while re-adding us, which will compute a correct set of
132 // sizes.
133 if (!container_ || !container_->delegate())
134 return;
136 int old_arrow_height = arrow_height_;
137 int old_bar_height = bar_height_;
139 container_->delegate()->ComputeInfoBarElementSizes(
140 animation_, arrow_target_height_, bar_target_height_, &arrow_height_,
141 &arrow_half_width_, &bar_height_);
143 // Don't re-layout if nothing has changed, e.g. because the animation step was
144 // not large enough to actually change the heights by at least a pixel.
145 bool heights_differ =
146 (old_arrow_height != arrow_height_) || (old_bar_height != bar_height_);
147 if (heights_differ)
148 PlatformSpecificOnHeightsRecalculated();
150 if (heights_differ || force_notify)
151 container_->OnInfoBarStateChanged(animation_.is_animating());
154 void InfoBar::MaybeDelete() {
155 if (!owner_ && (animation_.GetCurrentValue() == 0.0)) {
156 if (container_)
157 container_->RemoveInfoBar(this);
158 delete this;
162 } // namespace infobars