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 "chrome/browser/ui/infobar_container_delegate.h"
6 #include "ui/gfx/animation/slide_animation.h"
8 #if defined(TOOLKIT_VIEWS)
9 #include "ui/views/window/non_client_view.h"
13 #if defined(OS_MACOSX)
14 const int InfoBarContainerDelegate::kSeparatorLineHeight
= 1;
15 const int InfoBarContainerDelegate::kDefaultArrowTargetHeight
= 11;
16 #elif defined(TOOLKIT_VIEWS)
17 // Views comes second until the Mac browser is Views-based.
18 const int InfoBarContainerDelegate::kSeparatorLineHeight
=
19 views::NonClientFrameView::kClientEdgeThickness
;
20 const int InfoBarContainerDelegate::kDefaultArrowTargetHeight
= 9;
23 const int InfoBarContainerDelegate::kDefaultBarTargetHeight
= 36;
24 const int InfoBarContainerDelegate::kMaximumArrowTargetHeight
= 24;
25 const int InfoBarContainerDelegate::kDefaultArrowTargetHalfWidth
=
26 kDefaultArrowTargetHeight
;
27 const int InfoBarContainerDelegate::kMaximumArrowTargetHalfWidth
= 14;
29 InfoBarContainerDelegate::InfoBarContainerDelegate()
30 : top_arrow_target_height_(kDefaultArrowTargetHeight
) {
33 InfoBarContainerDelegate::~InfoBarContainerDelegate() {
36 void InfoBarContainerDelegate::SetMaxTopArrowHeight(
38 infobars::InfoBarContainer
* container
) {
39 // Decrease the height by the arrow stroke thickness, which is the separator
40 // line height, because the infobar arrow target heights are without-stroke.
41 top_arrow_target_height_
= std::min(
42 std::max(height
- kSeparatorLineHeight
, 0), kMaximumArrowTargetHeight
);
43 container
->UpdateInfoBarArrowTargetHeights();
46 int InfoBarContainerDelegate::ArrowTargetHeightForInfoBar(
48 const gfx::SlideAnimation
& animation
) const {
49 if (!DrawInfoBarArrows(nullptr))
52 return top_arrow_target_height_
;
53 if ((index
> 1) || animation
.IsShowing())
54 return kDefaultArrowTargetHeight
;
55 // When the first infobar is animating closed, we animate the second infobar's
56 // arrow target height from the default to the top target height. Note that
57 // the animation values here are going from 1.0 -> 0.0 as the top bar closes.
58 return top_arrow_target_height_
+ static_cast<int>(
59 (kDefaultArrowTargetHeight
- top_arrow_target_height_
) *
60 animation
.GetCurrentValue());
63 void InfoBarContainerDelegate::ComputeInfoBarElementSizes(
64 const gfx::SlideAnimation
& animation
,
65 int arrow_target_height
,
66 int bar_target_height
,
68 int* arrow_half_width
,
69 int* bar_height
) const {
70 // Find the desired arrow height/half-width. The arrow area is
71 // *arrow_height * *arrow_half_width. When the bar is opening or closing,
72 // scaling each of these with the square root of the animation value causes a
73 // linear animation of the area, which matches the perception of the animation
74 // of the bar portion.
75 double scale_factor
= sqrt(animation
.GetCurrentValue());
76 *arrow_height
= static_cast<int>(arrow_target_height
* scale_factor
);
77 if (animation
.is_animating()) {
78 *arrow_half_width
= static_cast<int>(
79 std::min(arrow_target_height
, kMaximumArrowTargetHalfWidth
) *
82 // When the infobar is not animating (i.e. fully open), we set the
83 // half-width to be proportionally the same distance between its default and
84 // maximum values as the height is between its.
85 *arrow_half_width
= kDefaultArrowTargetHalfWidth
+
86 ((kMaximumArrowTargetHalfWidth
- kDefaultArrowTargetHalfWidth
) *
87 ((*arrow_height
- kDefaultArrowTargetHeight
) /
88 (kMaximumArrowTargetHeight
- kDefaultArrowTargetHeight
)));
90 // Add pixels for the stroke, if the arrow is to be visible at all. Without
91 // this, changing the arrow height from 0 to kSeparatorLineHeight would
92 // produce no visible effect, because the stroke would paint atop the divider
93 // line above the infobar.
95 *arrow_height
+= kSeparatorLineHeight
;
97 *bar_height
= animation
.CurrentValueBetween(
99 (bar_target_height
== -1) ? kDefaultBarTargetHeight
: bar_target_height
);