[Metrics] Make MetricsStateManager take a callback param to check if UMA is enabled.
[chromium-blink-merge.git] / chrome / browser / ui / views / autofill / autofill_popup_base_view.cc
blobdb527c8ec612dd7f1fcff05b1edf3de546b9ae51
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/views/autofill/autofill_popup_base_view.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/message_loop/message_loop.h"
10 #include "chrome/browser/ui/autofill/popup_constants.h"
11 #include "ui/views/border.h"
12 #include "ui/views/widget/widget.h"
13 #include "ui/wm/core/window_animations.h"
15 namespace autofill {
17 const SkColor AutofillPopupBaseView::kBorderColor =
18 SkColorSetARGB(0xFF, 0xC7, 0xCA, 0xCE);
19 const SkColor AutofillPopupBaseView::kHoveredBackgroundColor =
20 SkColorSetARGB(0xFF, 0xCD, 0xCD, 0xCD);
21 const SkColor AutofillPopupBaseView::kItemTextColor =
22 SkColorSetARGB(0xFF, 0x7F, 0x7F, 0x7F);
23 const SkColor AutofillPopupBaseView::kPopupBackground =
24 SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF);
25 const SkColor AutofillPopupBaseView::kValueTextColor =
26 SkColorSetARGB(0xFF, 0x00, 0x00, 0x00);
27 const SkColor AutofillPopupBaseView::kWarningTextColor =
28 SkColorSetARGB(0xFF, 0x7F, 0x7F, 0x7F);
30 AutofillPopupBaseView::AutofillPopupBaseView(
31 AutofillPopupViewDelegate* delegate,
32 views::Widget* observing_widget)
33 : delegate_(delegate),
34 observing_widget_(observing_widget),
35 weak_ptr_factory_(this) {}
37 AutofillPopupBaseView::~AutofillPopupBaseView() {
38 if (delegate_) {
39 delegate_->ViewDestroyed();
41 RemoveObserver();
45 void AutofillPopupBaseView::DoShow() {
46 const bool initialize_widget = !GetWidget();
47 if (initialize_widget) {
48 observing_widget_->AddObserver(this);
50 views::FocusManager* focus_manager = observing_widget_->GetFocusManager();
51 focus_manager->RegisterAccelerator(
52 ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE),
53 ui::AcceleratorManager::kNormalPriority,
54 this);
55 focus_manager->RegisterAccelerator(
56 ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE),
57 ui::AcceleratorManager::kNormalPriority,
58 this);
60 // The widget is destroyed by the corresponding NativeWidget, so we use
61 // a weak pointer to hold the reference and don't have to worry about
62 // deletion.
63 views::Widget* widget = new views::Widget;
64 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
65 params.delegate = this;
66 params.parent = container_view();
67 widget->Init(params);
68 widget->SetContentsView(this);
70 // No animation for popup appearance (too distracting).
71 wm::SetWindowVisibilityAnimationTransition(
72 widget->GetNativeView(), wm::ANIMATE_HIDE);
75 SetBorder(views::Border::CreateSolidBorder(kPopupBorderThickness,
76 kBorderColor));
78 DoUpdateBoundsAndRedrawPopup();
79 GetWidget()->Show();
81 // Showing the widget can change native focus (which would result in an
82 // immediate hiding of the popup). Only start observing after shown.
83 if (initialize_widget)
84 views::WidgetFocusManager::GetInstance()->AddFocusChangeListener(this);
87 void AutofillPopupBaseView::DoHide() {
88 // The controller is no longer valid after it hides us.
89 delegate_ = NULL;
91 RemoveObserver();
93 if (GetWidget()) {
94 // Don't call CloseNow() because some of the functions higher up the stack
95 // assume the the widget is still valid after this point.
96 // http://crbug.com/229224
97 // NOTE: This deletes |this|.
98 GetWidget()->Close();
99 } else {
100 delete this;
104 void AutofillPopupBaseView::RemoveObserver() {
105 observing_widget_->GetFocusManager()->UnregisterAccelerators(this);
106 observing_widget_->RemoveObserver(this);
107 views::WidgetFocusManager::GetInstance()->RemoveFocusChangeListener(this);
110 void AutofillPopupBaseView::DoUpdateBoundsAndRedrawPopup() {
111 GetWidget()->SetBounds(delegate_->popup_bounds());
112 SchedulePaint();
115 void AutofillPopupBaseView::OnNativeFocusChange(
116 gfx::NativeView focused_before,
117 gfx::NativeView focused_now) {
118 if (GetWidget() && GetWidget()->GetNativeView() != focused_now)
119 HideController();
122 void AutofillPopupBaseView::OnWidgetBoundsChanged(views::Widget* widget,
123 const gfx::Rect& new_bounds) {
124 DCHECK_EQ(widget, observing_widget_);
125 HideController();
128 void AutofillPopupBaseView::OnMouseCaptureLost() {
129 ClearSelection();
132 bool AutofillPopupBaseView::OnMouseDragged(const ui::MouseEvent& event) {
133 if (HitTestPoint(event.location())) {
134 SetSelection(event.location());
136 // We must return true in order to get future OnMouseDragged and
137 // OnMouseReleased events.
138 return true;
141 // If we move off of the popup, we lose the selection.
142 ClearSelection();
143 return false;
146 void AutofillPopupBaseView::OnMouseExited(const ui::MouseEvent& event) {
147 // Pressing return causes the cursor to hide, which will generate an
148 // OnMouseExited event. Pressing return should activate the current selection
149 // via AcceleratorPressed, so we need to let that run first.
150 base::MessageLoop::current()->PostTask(
151 FROM_HERE,
152 base::Bind(&AutofillPopupBaseView::ClearSelection,
153 weak_ptr_factory_.GetWeakPtr()));
156 void AutofillPopupBaseView::OnMouseMoved(const ui::MouseEvent& event) {
157 if (HitTestPoint(event.location()))
158 SetSelection(event.location());
159 else
160 ClearSelection();
163 bool AutofillPopupBaseView::OnMousePressed(const ui::MouseEvent& event) {
164 return true;
167 void AutofillPopupBaseView::OnMouseReleased(const ui::MouseEvent& event) {
168 // We only care about the left click.
169 if (event.IsOnlyLeftMouseButton() && HitTestPoint(event.location()))
170 AcceptSelection(event.location());
173 void AutofillPopupBaseView::OnGestureEvent(ui::GestureEvent* event) {
174 switch (event->type()) {
175 case ui::ET_GESTURE_TAP_DOWN:
176 case ui::ET_GESTURE_SCROLL_BEGIN:
177 case ui::ET_GESTURE_SCROLL_UPDATE:
178 if (HitTestPoint(event->location()))
179 SetSelection(event->location());
180 else
181 ClearSelection();
182 break;
183 case ui::ET_GESTURE_TAP:
184 case ui::ET_GESTURE_SCROLL_END:
185 if (HitTestPoint(event->location()))
186 AcceptSelection(event->location());
187 else
188 ClearSelection();
189 break;
190 case ui::ET_GESTURE_TAP_CANCEL:
191 case ui::ET_SCROLL_FLING_START:
192 ClearSelection();
193 break;
194 default:
195 return;
197 event->SetHandled();
200 bool AutofillPopupBaseView::AcceleratorPressed(
201 const ui::Accelerator& accelerator) {
202 DCHECK_EQ(accelerator.modifiers(), ui::EF_NONE);
204 if (accelerator.key_code() == ui::VKEY_ESCAPE) {
205 HideController();
206 return true;
209 if (accelerator.key_code() == ui::VKEY_RETURN)
210 return delegate_->AcceptSelectedLine();
212 NOTREACHED();
213 return false;
216 void AutofillPopupBaseView::SetSelection(const gfx::Point& point) {
217 if (delegate_)
218 delegate_->SetSelectionAtPoint(point);
221 void AutofillPopupBaseView::AcceptSelection(const gfx::Point& point) {
222 if (!delegate_)
223 return;
225 delegate_->SetSelectionAtPoint(point);
226 delegate_->AcceptSelectedLine();
229 void AutofillPopupBaseView::ClearSelection() {
230 if (delegate_)
231 delegate_->SelectionCleared();
234 void AutofillPopupBaseView::HideController() {
235 if (delegate_)
236 delegate_->Hide();
239 gfx::NativeView AutofillPopupBaseView::container_view() {
240 return delegate_->container_view();
244 } // namespace autofill