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