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

Side by Side Diff: chrome/browser/ui/views/autofill/info_bubble.cc

Issue 55243005: Implement learn more bubble on views. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 1 month 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 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.
4
5 #include "chrome/browser/ui/views/autofill/info_bubble.h"
6
7 #include "base/i18n/rtl.h"
8 #include "ui/gfx/point.h"
9 #include "ui/gfx/rect.h"
10 #include "ui/gfx/size.h"
11 #include "ui/gfx/text_constants.h"
12 #include "ui/views/bubble/bubble_border.h"
13 #include "ui/views/bubble/bubble_frame_view.h"
14 #include "ui/views/controls/combobox/combobox.h"
15 #include "ui/views/controls/label.h"
16 #include "ui/views/layout/fill_layout.h"
17 #include "ui/views/layout/layout_constants.h"
18 #include "ui/views/widget/widget.h"
19
20 namespace autofill {
21
22 namespace {
23
24 // The visible width of bubble borders (differs from the actual width) in px.
25 const int kBubbleBorderVisibleWidth = 1;
26
27 // The margin between the content of the error bubble and its border.
28 const int kInfoBubbleHorizontalMargin = 14;
29 const int kInfoBubbleVerticalMargin = 12;
30
31 } // namespace
32
33 InfoBubble::InfoBubble(views::View* anchor, const base::string16& message)
34 : anchor_(anchor),
35 show_above_anchor_(
Evan Stade 2013/11/05 19:57:23 I think it would be slightly nicer if there were a
36 anchor->GetClassName() == views::Combobox::kViewClassName),
37 align_to_anchor_edge_(false),
38 preferred_width_(233) {
39 DCHECK(anchor_);
40 SetAnchorView(anchor_);
41
42 // TODO(dbeam): currently we assume that combobox menus always show downward
43 // (which isn't true). If the invalid combobox is low enough on the screen,
44 // its menu will actually show upward and obscure the bubble. Figure out when
45 // this might happen and adjust |show_above_anchor_| accordingly. This is not
46 // that big of deal because it rarely happens in practice.
47 if (show_above_anchor_) {
48 set_arrow(ShouldArrowGoOnTheRight() ? views::BubbleBorder::BOTTOM_RIGHT :
49 views::BubbleBorder::BOTTOM_LEFT);
50 } else {
51 set_arrow(ShouldArrowGoOnTheRight() ? views::BubbleBorder::TOP_RIGHT :
52 views::BubbleBorder::TOP_LEFT);
53 }
54
55 set_margins(gfx::Insets(kInfoBubbleVerticalMargin,
56 kInfoBubbleHorizontalMargin,
57 kInfoBubbleVerticalMargin,
58 kInfoBubbleHorizontalMargin));
59 set_use_focusless(true);
60
61 SetLayoutManager(new views::FillLayout);
62 views::Label* label = new views::Label(message);
63 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
64 label->SetMultiLine(true);
65 AddChildView(label);
66 }
67
68 InfoBubble::~InfoBubble() {
69 DCHECK(!widget_);
70 }
71
72 void InfoBubble::Show() {
73 widget_ = views::BubbleDelegateView::CreateBubble(this);
74 UpdatePosition();
75 }
76
77 void InfoBubble::Hide() {
78 views::Widget* widget = GetWidget();
79 if (widget && !widget->IsClosed())
80 widget->Close();
81 }
82
83 void InfoBubble::UpdatePosition() {
84 if (!widget_)
85 return;
86
87 if (!anchor_->GetVisibleBounds().IsEmpty()) {
88 SizeToContents();
89 widget_->SetVisibilityChangedAnimationsEnabled(true);
90 widget_->ShowInactive();
91 } else {
92 widget_->SetVisibilityChangedAnimationsEnabled(false);
93 widget_->Hide();
94 }
95 }
96
97 gfx::Size InfoBubble::GetPreferredSize() {
98 int pref_width = preferred_width_;
99 pref_width -= GetBubbleFrameView()->GetInsets().width();
100 pref_width -= 2 * kBubbleBorderVisibleWidth;
101 return gfx::Size(pref_width, GetHeightForWidth(pref_width));
102 }
103
104 gfx::Rect InfoBubble::GetBubbleBounds() {
105 gfx::Rect bounds = views::BubbleDelegateView::GetBubbleBounds();
106 gfx::Rect anchor_rect = GetAnchorRect();
107
108 if (show_above_anchor_)
109 bounds.set_y(anchor_rect.y() - GetBubbleFrameView()->height());
110 else
111 bounds.set_y(anchor_rect.bottom());
112
113 if (align_to_anchor_edge_) {
114 anchor_rect.Inset(-GetBubbleFrameView()->bubble_border()->GetInsets());
115 bounds.set_x(ShouldArrowGoOnTheRight() ?
116 anchor_rect.right() - bounds.width() - kBubbleBorderVisibleWidth :
117 anchor_rect.x() + kBubbleBorderVisibleWidth);
118 }
119
120 return bounds;
121 }
122
123 void InfoBubble::OnWidgetClosing(views::Widget* widget) {
124 if (widget == widget_)
125 widget_ = NULL;
126 }
127
128 bool InfoBubble::ShouldFlipArrowForRtl() const {
129 return false;
130 }
131
132 bool InfoBubble::ShouldArrowGoOnTheRight() {
133 views::View* container = anchor_->GetWidget()->non_client_view();
134 DCHECK(container->Contains(anchor_));
135
136 gfx::Point anchor_offset;
137 views::View::ConvertPointToTarget(anchor_, container, &anchor_offset);
138 anchor_offset.Offset(-container_insets_.left(), 0);
139
140 if (base::i18n::IsRTL()) {
141 int anchor_right_x = anchor_offset.x() + anchor_->width();
142 return anchor_right_x >= preferred_width_;
143 }
144
145 int container_width = container->width() - container_insets_.width();
146 return anchor_offset.x() + preferred_width_ > container_width;
147 }
148
149 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698