Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / ui / views / autofill / autofill_popup_base_view.cc
blob76926caaa72852162f583e719ed6e1cea4573cc4
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/focus/focus_manager.h"
13 #include "ui/views/widget/widget.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::FocusManager* focus_manager)
33 : delegate_(delegate),
34 focus_manager_(focus_manager),
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 focus_manager_->RegisterAccelerator(
49 ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE),
50 ui::AcceleratorManager::kNormalPriority,
51 this);
52 focus_manager_->RegisterAccelerator(
53 ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE),
54 ui::AcceleratorManager::kNormalPriority,
55 this);
57 // The widget is destroyed by the corresponding NativeWidget, so we use
58 // a weak pointer to hold the reference and don't have to worry about
59 // deletion.
60 views::Widget* widget = new views::Widget;
61 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
62 params.delegate = this;
63 params.parent = container_view();
64 widget->Init(params);
65 widget->SetContentsView(this);
67 // No animation for popup appearance (too distracting).
68 widget->SetVisibilityAnimationTransition(views::Widget::ANIMATE_HIDE);
70 show_time_ = base::Time::Now();
73 SetBorder(views::Border::CreateSolidBorder(kPopupBorderThickness,
74 kBorderColor));
76 DoUpdateBoundsAndRedrawPopup();
77 GetWidget()->Show();
79 // Showing the widget can change native focus (which would result in an
80 // immediate hiding of the popup). Only start observing after shown.
81 if (initialize_widget)
82 views::WidgetFocusManager::GetInstance()->AddFocusChangeListener(this);
85 void AutofillPopupBaseView::DoHide() {
86 // The controller is no longer valid after it hides us.
87 delegate_ = NULL;
89 RemoveObserver();
91 if (GetWidget()) {
92 // Don't call CloseNow() because some of the functions higher up the stack
93 // assume the the widget is still valid after this point.
94 // http://crbug.com/229224
95 // NOTE: This deletes |this|.
96 GetWidget()->Close();
97 } else {
98 delete this;
102 void AutofillPopupBaseView::RemoveObserver() {
103 focus_manager_->UnregisterAccelerators(this);
104 views::WidgetFocusManager::GetInstance()->RemoveFocusChangeListener(this);
107 void AutofillPopupBaseView::DoUpdateBoundsAndRedrawPopup() {
108 GetWidget()->SetBounds(delegate_->popup_bounds());
109 SchedulePaint();
112 void AutofillPopupBaseView::OnNativeFocusChanged(gfx::NativeView focused_now) {
113 if (GetWidget() && GetWidget()->GetNativeView() != focused_now)
114 HideController();
117 void AutofillPopupBaseView::OnMouseCaptureLost() {
118 ClearSelection();
121 bool AutofillPopupBaseView::OnMouseDragged(const ui::MouseEvent& event) {
122 if (HitTestPoint(event.location())) {
123 SetSelection(event.location());
125 // We must return true in order to get future OnMouseDragged and
126 // OnMouseReleased events.
127 return true;
130 // If we move off of the popup, we lose the selection.
131 ClearSelection();
132 return false;
135 void AutofillPopupBaseView::OnMouseExited(const ui::MouseEvent& event) {
136 // Pressing return causes the cursor to hide, which will generate an
137 // OnMouseExited event. Pressing return should activate the current selection
138 // via AcceleratorPressed, so we need to let that run first.
139 base::MessageLoop::current()->PostTask(
140 FROM_HERE,
141 base::Bind(&AutofillPopupBaseView::ClearSelection,
142 weak_ptr_factory_.GetWeakPtr()));
145 void AutofillPopupBaseView::OnMouseMoved(const ui::MouseEvent& event) {
146 // A synthesized mouse move will be sent when the popup is first shown.
147 // Don't preview a suggestion if the mouse happens to be hovering there.
148 #if defined(OS_WIN)
149 // TODO(rouslan): Use event.time_stamp() and ui::EventTimeForNow() when they
150 // become comparable. http://crbug.com/453559
151 if (base::Time::Now() - show_time_ <= base::TimeDelta::FromMilliseconds(50))
152 return;
153 #else
154 if (event.flags() & ui::EF_IS_SYNTHESIZED)
155 return;
156 #endif
158 if (HitTestPoint(event.location()))
159 SetSelection(event.location());
160 else
161 ClearSelection();
164 bool AutofillPopupBaseView::OnMousePressed(const ui::MouseEvent& event) {
165 return event.GetClickCount() == 1;
168 void AutofillPopupBaseView::OnMouseReleased(const ui::MouseEvent& event) {
169 // We only care about the left click.
170 if (event.IsOnlyLeftMouseButton() && HitTestPoint(event.location()))
171 AcceptSelection(event.location());
174 void AutofillPopupBaseView::OnGestureEvent(ui::GestureEvent* event) {
175 switch (event->type()) {
176 case ui::ET_GESTURE_TAP_DOWN:
177 case ui::ET_GESTURE_SCROLL_BEGIN:
178 case ui::ET_GESTURE_SCROLL_UPDATE:
179 if (HitTestPoint(event->location()))
180 SetSelection(event->location());
181 else
182 ClearSelection();
183 break;
184 case ui::ET_GESTURE_TAP:
185 case ui::ET_GESTURE_SCROLL_END:
186 if (HitTestPoint(event->location()))
187 AcceptSelection(event->location());
188 else
189 ClearSelection();
190 break;
191 case ui::ET_GESTURE_TAP_CANCEL:
192 case ui::ET_SCROLL_FLING_START:
193 ClearSelection();
194 break;
195 default:
196 return;
198 event->SetHandled();
201 bool AutofillPopupBaseView::AcceleratorPressed(
202 const ui::Accelerator& accelerator) {
203 DCHECK_EQ(accelerator.modifiers(), ui::EF_NONE);
205 if (accelerator.key_code() == ui::VKEY_ESCAPE) {
206 HideController();
207 return true;
210 if (accelerator.key_code() == ui::VKEY_RETURN)
211 return delegate_->AcceptSelectedLine();
213 NOTREACHED();
214 return false;
217 void AutofillPopupBaseView::SetSelection(const gfx::Point& point) {
218 if (delegate_)
219 delegate_->SetSelectionAtPoint(point);
222 void AutofillPopupBaseView::AcceptSelection(const gfx::Point& point) {
223 if (!delegate_)
224 return;
226 delegate_->SetSelectionAtPoint(point);
227 delegate_->AcceptSelectedLine();
230 void AutofillPopupBaseView::ClearSelection() {
231 if (delegate_)
232 delegate_->SelectionCleared();
235 void AutofillPopupBaseView::HideController() {
236 if (delegate_)
237 delegate_->Hide();
240 gfx::NativeView AutofillPopupBaseView::container_view() {
241 return delegate_->container_view();
244 } // namespace autofill