Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: chrome/browser/ui/views/infobars/infobar_container_view.cc

Issue 1800373002: [MD] replace infobar bottom solid line separator with a shadow. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: self review Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/infobars/infobar_container_view.h" 5 #include "chrome/browser/ui/views/infobars/infobar_container_view.h"
6 6
7 #include "chrome/browser/ui/infobar_container_delegate.h"
7 #include "chrome/browser/ui/view_ids.h" 8 #include "chrome/browser/ui/view_ids.h"
8 #include "chrome/browser/ui/views/infobars/infobar_view.h" 9 #include "chrome/browser/ui/views/infobars/infobar_view.h"
9 #include "chrome/grit/generated_resources.h" 10 #include "chrome/grit/generated_resources.h"
10 #include "ui/accessibility/ax_view_state.h" 11 #include "ui/accessibility/ax_view_state.h"
11 #include "ui/base/l10n/l10n_util.h" 12 #include "ui/base/l10n/l10n_util.h"
13 #include "ui/base/material_design/material_design_controller.h"
14 #include "ui/gfx/canvas.h"
15 #include "ui/gfx/skia_util.h"
12 #include "ui/views/view_targeter.h" 16 #include "ui/views/view_targeter.h"
13 17
18 namespace {
19
20 // The content shadow is drawn in two stages. A darker, shorter shadow is
21 // blended with a taller, lighter shadow. The heights are in dp.
22 const int kSmallShadowHeight = 1;
23 const int kLargeShadowHeight = 3;
24 const SkAlpha kSmallShadowAlpha = 0x33;
25 const SkAlpha kLargeShadowAlpha = 0x1A;
26
27 class ContentShadow : public views::View {
28 public:
29 ContentShadow() {
Peter Kasting 2016/03/16 03:10:27 Nit: I tend to find out-of-line definitions of met
Evan Stade 2016/03/16 19:29:51 Acknowledged.
30 SetPaintToLayer(true);
31 layer()->SetFillsBoundsOpaquely(false);
32 }
33 ~ContentShadow() override {}
34
35 // views::View:
36 void OnPaint(gfx::Canvas* canvas) override {
Peter Kasting 2016/03/16 03:10:27 Nit: Could be private
Evan Stade 2016/03/16 19:29:52 I guess I should make it protected. I prefer to ke
37 // The first shader (small shadow) blurs from 0 to kSmallShadowHeight.
38 SkPaint paint;
39 skia::RefPtr<SkShader> shader = gfx::CreateGradientShader(
Peter Kasting 2016/03/16 03:10:27 I assume we want a gradient shader because at scal
Evan Stade 2016/03/16 19:29:51 right, that's why I decided against drawing a soli
40 0, kSmallShadowHeight, SkColorSetA(SK_ColorBLACK, kSmallShadowAlpha),
41 SkColorSetA(SK_ColorBLACK, 0));
Peter Kasting 2016/03/16 03:10:27 Nit: Could use SK_AlphaTRANSPARENT in place of 0,
Evan Stade 2016/03/16 19:29:51 will give it a go.
42 paint.setShader(shader.get());
43 gfx::Rect small_shadow_bounds = GetLocalBounds();
44 small_shadow_bounds.set_height(kSmallShadowHeight);
45 canvas->DrawRect(small_shadow_bounds, paint);
46
47 // The second shader (large shadow) is solid from 0 to kSmallShadowHeight
48 // (blending with the first shader) and then blurs from kSmallShadowHeight
49 // to kLargeShadowHeight.
50 shader =
51 gfx::CreateGradientShader(kSmallShadowHeight, height(),
52 SkColorSetA(SK_ColorBLACK, kLargeShadowAlpha),
53 SkColorSetA(SK_ColorBLACK, 0));
54 paint.setShader(shader.get());
55 canvas->DrawRect(GetLocalBounds(), paint);
56 }
57
58 private:
59 DISALLOW_COPY_AND_ASSIGN(ContentShadow);
60 };
61
62 } // namespace
63
14 // static 64 // static
15 const char InfoBarContainerView::kViewClassName[] = "InfoBarContainerView"; 65 const char InfoBarContainerView::kViewClassName[] = "InfoBarContainerView";
16 66
17 InfoBarContainerView::InfoBarContainerView(Delegate* delegate) 67 InfoBarContainerView::InfoBarContainerView(Delegate* delegate)
18 : infobars::InfoBarContainer(delegate) { 68 : infobars::InfoBarContainer(delegate), content_shadow_(nullptr) {
19 set_id(VIEW_ID_INFO_BAR_CONTAINER); 69 set_id(VIEW_ID_INFO_BAR_CONTAINER);
20 SetEventTargeter(make_scoped_ptr(new views::ViewTargeter(this))); 70 if (ui::MaterialDesignController::IsModeMaterial()) {
71 content_shadow_ = new ContentShadow();
72 AddChildView(content_shadow_);
73 }
21 } 74 }
22 75
23 InfoBarContainerView::~InfoBarContainerView() { 76 InfoBarContainerView::~InfoBarContainerView() {
24 RemoveAllInfoBarsForDestruction(); 77 RemoveAllInfoBarsForDestruction();
25 } 78 }
26 79
27 gfx::Size InfoBarContainerView::GetPreferredSize() const { 80 gfx::Size InfoBarContainerView::GetPreferredSize() const {
28 int total_height; 81 int total_height;
29 GetVerticalOverlap(&total_height); 82 int overlap = GetVerticalOverlap(&total_height);
Peter Kasting 2016/03/16 03:10:27 Nit: Can inline into next line
Evan Stade 2016/03/16 19:29:51 perhaps this works but it's not clear to me that i
Peter Kasting 2016/03/17 03:30:01 Oh, never mind, I didn't even see that the call wa
83 total_height -= overlap;
84
85 // No need to reserve space for the bottom bar's separator; the shadow is good
86 // enough.
87 if (ui::MaterialDesignController::IsModeMaterial())
88 total_height -= InfoBarContainerDelegate::kSeparatorLineHeight;
89
30 gfx::Size size(0, total_height); 90 gfx::Size size(0, total_height);
31 for (int i = 0; i < child_count(); ++i) 91 for (int i = 0; i < child_count(); ++i)
32 size.SetToMax(gfx::Size(child_at(i)->GetPreferredSize().width(), 0)); 92 size.SetToMax(gfx::Size(child_at(i)->GetPreferredSize().width(), 0));
33 return size; 93 return size;
34 } 94 }
35 95
36 const char* InfoBarContainerView::GetClassName() const { 96 const char* InfoBarContainerView::GetClassName() const {
37 return kViewClassName; 97 return kViewClassName;
38 } 98 }
39 99
40 void InfoBarContainerView::Layout() { 100 void InfoBarContainerView::Layout() {
41 int top = GetVerticalOverlap(NULL); 101 int top = 0;
42 102
43 for (int i = 0; i < child_count(); ++i) { 103 for (int i = 0; i < child_count(); ++i) {
104 if (child_at(i) == content_shadow_)
105 continue;
106
44 InfoBarView* child = static_cast<InfoBarView*>(child_at(i)); 107 InfoBarView* child = static_cast<InfoBarView*>(child_at(i));
45 top -= child->arrow_height(); 108 top -= child->arrow_height();
46 int child_height = child->total_height(); 109 int child_height = child->total_height();
110
111 // Trim off the bottom bar's separator; the shadow is good enough.
112 if (ui::MaterialDesignController::IsModeMaterial() &&
113 i == child_count() - 2) {
Peter Kasting 2016/03/16 03:10:27 Nit: It might be good for a comment to explain why
Evan Stade 2016/03/16 19:29:51 will add
114 child_height -= InfoBarContainerDelegate::kSeparatorLineHeight;
115 }
47 child->SetBounds(0, top, width(), child_height); 116 child->SetBounds(0, top, width(), child_height);
48 top += child_height; 117 top += child_height;
49 } 118 }
119
120 if (ui::MaterialDesignController::IsModeMaterial())
121 content_shadow_->SetBounds(0, top, width(), kLargeShadowHeight);
50 } 122 }
51 123
52 void InfoBarContainerView::GetAccessibleState(ui::AXViewState* state) { 124 void InfoBarContainerView::GetAccessibleState(ui::AXViewState* state) {
53 state->role = ui::AX_ROLE_GROUP; 125 state->role = ui::AX_ROLE_GROUP;
54 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_INFOBAR_CONTAINER); 126 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_INFOBAR_CONTAINER);
55 } 127 }
56 128
57 void InfoBarContainerView::PlatformSpecificAddInfoBar( 129 void InfoBarContainerView::PlatformSpecificAddInfoBar(
58 infobars::InfoBar* infobar, 130 infobars::InfoBar* infobar,
59 size_t position) { 131 size_t position) {
60 AddChildViewAt(static_cast<InfoBarView*>(infobar), 132 AddChildViewAt(static_cast<InfoBarView*>(infobar),
61 static_cast<int>(position)); 133 static_cast<int>(position));
62 } 134 }
63 135
64 void InfoBarContainerView::PlatformSpecificRemoveInfoBar( 136 void InfoBarContainerView::PlatformSpecificRemoveInfoBar(
65 infobars::InfoBar* infobar) { 137 infobars::InfoBar* infobar) {
66 RemoveChildView(static_cast<InfoBarView*>(infobar)); 138 RemoveChildView(static_cast<InfoBarView*>(infobar));
67 } 139 }
68
69 bool InfoBarContainerView::DoesIntersectRect(const View* target,
70 const gfx::Rect& rect) const {
71 DCHECK_EQ(this, target);
72 // Only events that intersect the portion below the arrow are interesting.
73 gfx::Rect non_arrow_bounds = GetLocalBounds();
74 non_arrow_bounds.Inset(0, GetVerticalOverlap(nullptr), 0, 0);
75 return rect.Intersects(non_arrow_bounds);
76 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698