NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / ui / views / autofill / autofill_popup_base_view.cc
blob71b056a9281102564dab64c1c0774002a1873f57
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 "chrome/browser/ui/autofill/popup_constants.h"
8 #include "ui/gfx/point.h"
9 #include "ui/gfx/screen.h"
10 #include "ui/views/border.h"
11 #include "ui/views/event_utils.h"
12 #include "ui/views/widget/widget.h"
14 #if defined(USE_AURA)
15 #include "ui/views/corewm/window_animations.h"
16 #endif
18 namespace autofill {
20 const SkColor AutofillPopupBaseView::kBorderColor =
21 SkColorSetARGB(0xFF, 0xC7, 0xCA, 0xCE);
22 const SkColor AutofillPopupBaseView::kHoveredBackgroundColor =
23 SkColorSetARGB(0xFF, 0xCD, 0xCD, 0xCD);
24 const SkColor AutofillPopupBaseView::kItemTextColor =
25 SkColorSetARGB(0xFF, 0x7F, 0x7F, 0x7F);
26 const SkColor AutofillPopupBaseView::kPopupBackground =
27 SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF);
28 const SkColor AutofillPopupBaseView::kValueTextColor =
29 SkColorSetARGB(0xFF, 0x00, 0x00, 0x00);
30 const SkColor AutofillPopupBaseView::kWarningTextColor =
31 SkColorSetARGB(0xFF, 0x7F, 0x7F, 0x7F);
33 AutofillPopupBaseView::AutofillPopupBaseView(
34 AutofillPopupViewDelegate* delegate,
35 views::Widget* observing_widget)
36 : delegate_(delegate),
37 observing_widget_(observing_widget) {}
38 AutofillPopupBaseView::~AutofillPopupBaseView() {
39 if (delegate_) {
40 delegate_->ViewDestroyed();
42 RemoveObserver();
46 void AutofillPopupBaseView::DoShow() {
47 if (!GetWidget()) {
48 observing_widget_->AddObserver(this);
50 // The widget is destroyed by the corresponding NativeWidget, so we use
51 // a weak pointer to hold the reference and don't have to worry about
52 // deletion.
53 views::Widget* widget = new views::Widget;
54 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
55 params.delegate = this;
56 params.parent = container_view();
57 widget->Init(params);
58 widget->SetContentsView(this);
59 #if defined(USE_AURA)
60 // No animation for popup appearance (too distracting).
61 views::corewm::SetWindowVisibilityAnimationTransition(
62 widget->GetNativeView(), views::corewm::ANIMATE_HIDE);
63 #endif
66 SetBorder(views::Border::CreateSolidBorder(kPopupBorderThickness,
67 kBorderColor));
69 DoUpdateBoundsAndRedrawPopup();
70 GetWidget()->Show();
72 if (ShouldHideOnOutsideClick())
73 GetWidget()->SetCapture(this);
76 void AutofillPopupBaseView::DoHide() {
77 // The controller is no longer valid after it hides us.
78 delegate_ = NULL;
80 RemoveObserver();
82 if (GetWidget()) {
83 // Don't call CloseNow() because some of the functions higher up the stack
84 // assume the the widget is still valid after this point.
85 // http://crbug.com/229224
86 // NOTE: This deletes |this|.
87 GetWidget()->Close();
88 } else {
89 delete this;
93 void AutofillPopupBaseView::RemoveObserver() {
94 observing_widget_->RemoveObserver(this);
97 void AutofillPopupBaseView::DoUpdateBoundsAndRedrawPopup() {
98 GetWidget()->SetBounds(delegate_->popup_bounds());
99 SchedulePaint();
102 void AutofillPopupBaseView::OnWidgetBoundsChanged(views::Widget* widget,
103 const gfx::Rect& new_bounds) {
104 DCHECK_EQ(widget, observing_widget_);
105 HideController();
108 void AutofillPopupBaseView::OnMouseCaptureLost() {
109 ClearSelection();
112 bool AutofillPopupBaseView::OnMouseDragged(const ui::MouseEvent& event) {
113 if (HitTestPoint(event.location())) {
114 SetSelection(event.location());
116 // We must return true in order to get future OnMouseDragged and
117 // OnMouseReleased events.
118 return true;
121 // If we move off of the popup, we lose the selection.
122 ClearSelection();
123 return false;
126 void AutofillPopupBaseView::OnMouseExited(const ui::MouseEvent& event) {
127 ClearSelection();
130 void AutofillPopupBaseView::OnMouseMoved(const ui::MouseEvent& event) {
131 if (HitTestPoint(event.location()))
132 SetSelection(event.location());
133 else
134 ClearSelection();
137 bool AutofillPopupBaseView::OnMousePressed(const ui::MouseEvent& event) {
138 if (HitTestPoint(event.location()))
139 return true;
141 if (ShouldHideOnOutsideClick()) {
142 GetWidget()->ReleaseCapture();
144 gfx::Point screen_loc = event.location();
145 views::View::ConvertPointToScreen(this, &screen_loc);
147 ui::MouseEvent mouse_event = event;
148 mouse_event.set_location(screen_loc);
150 if (ShouldRepostEvent(mouse_event)) {
151 gfx::NativeView native_view = GetWidget()->GetNativeView();
152 gfx::Screen* screen = gfx::Screen::GetScreenFor(native_view);
153 gfx::NativeWindow window = screen->GetWindowAtScreenPoint(screen_loc);
154 views::RepostLocatedEvent(window, mouse_event);
157 HideController();
158 // |this| is now deleted.
161 return false;
164 void AutofillPopupBaseView::OnMouseReleased(const ui::MouseEvent& event) {
165 // Because this view can can be shown in response to a mouse press, it can
166 // receive an OnMouseReleased event just after showing. This breaks the mouse
167 // capture, so restart capturing here.
168 if (ShouldHideOnOutsideClick() && GetWidget())
169 GetWidget()->SetCapture(this);
171 // We only care about the left click.
172 if (event.IsOnlyLeftMouseButton() && HitTestPoint(event.location()))
173 AcceptSelection(event.location());
176 void AutofillPopupBaseView::OnGestureEvent(ui::GestureEvent* event) {
177 switch (event->type()) {
178 case ui::ET_GESTURE_TAP_DOWN:
179 case ui::ET_GESTURE_SCROLL_BEGIN:
180 case ui::ET_GESTURE_SCROLL_UPDATE:
181 if (HitTestPoint(event->location()))
182 SetSelection(event->location());
183 else
184 ClearSelection();
185 break;
186 case ui::ET_GESTURE_TAP:
187 case ui::ET_GESTURE_SCROLL_END:
188 if (HitTestPoint(event->location()))
189 SetSelection(event->location());
190 else
191 ClearSelection();
192 break;
193 case ui::ET_GESTURE_TAP_CANCEL:
194 case ui::ET_SCROLL_FLING_START:
195 ClearSelection();
196 break;
197 default:
198 return;
200 event->SetHandled();
203 void AutofillPopupBaseView::SetSelection(const gfx::Point& point) {
204 if (delegate_)
205 delegate_->SetSelectionAtPoint(point);
208 void AutofillPopupBaseView::AcceptSelection(const gfx::Point& point) {
209 if (delegate_)
210 delegate_->AcceptSelectionAtPoint(point);
213 void AutofillPopupBaseView::ClearSelection() {
214 if (delegate_)
215 delegate_->SelectionCleared();
218 bool AutofillPopupBaseView::ShouldHideOnOutsideClick() {
219 if (delegate_)
220 return delegate_->ShouldHideOnOutsideClick();
222 // |this| instance should be in the process of being destroyed, so the return
223 // value shouldn't matter.
224 return false;
227 void AutofillPopupBaseView::HideController() {
228 if (delegate_)
229 delegate_->Hide();
232 bool AutofillPopupBaseView::ShouldRepostEvent(const ui::MouseEvent& event) {
233 return delegate_->ShouldRepostEvent(event);
236 gfx::NativeView AutofillPopupBaseView::container_view() {
237 return delegate_->container_view();
241 } // namespace autofill