Infobar material design refresh: layout
[chromium-blink-merge.git] / chrome / browser / ui / infobar_container_delegate.cc
blob28244d5467dc701cd306be1aee3dc6107ef2693e
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"
12 #endif
14 // static
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;
23 #endif
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(
40 int height,
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(
50 size_t index,
51 const gfx::SlideAnimation& animation) const {
52 if (!DrawInfoBarArrows(nullptr))
53 return 0;
54 if (index == 0)
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,
70 int* arrow_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) *
83 scale_factor);
84 } else {
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.
97 if (*arrow_height)
98 *arrow_height += kSeparatorLineHeight;
100 int target_height = bar_target_height != -1
101 ? bar_target_height
102 : ui::MaterialDesignController::IsModeMaterial()
103 ? kDefaultBarTargetHeightMd
104 : kDefaultBarTargetHeight;
105 *bar_height = animation.CurrentValueBetween(0, target_height);