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"
15 #include "ui/views/corewm/window_animations.h"
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() {
40 delegate_
->ViewDestroyed();
46 void AutofillPopupBaseView::DoShow() {
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
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();
58 widget
->SetContentsView(this);
60 // No animation for popup appearance (too distracting).
61 views::corewm::SetWindowVisibilityAnimationTransition(
62 widget
->GetNativeView(), views::corewm::ANIMATE_HIDE
);
66 SetBorder(views::Border::CreateSolidBorder(kPopupBorderThickness
,
69 DoUpdateBoundsAndRedrawPopup();
72 if (ShouldHideOnOutsideClick())
73 GetWidget()->SetCapture(this);
76 void AutofillPopupBaseView::DoHide() {
77 // The controller is no longer valid after it hides us.
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|.
93 void AutofillPopupBaseView::RemoveObserver() {
94 observing_widget_
->RemoveObserver(this);
97 void AutofillPopupBaseView::DoUpdateBoundsAndRedrawPopup() {
98 GetWidget()->SetBounds(delegate_
->popup_bounds());
102 void AutofillPopupBaseView::OnWidgetBoundsChanged(views::Widget
* widget
,
103 const gfx::Rect
& new_bounds
) {
104 DCHECK_EQ(widget
, observing_widget_
);
108 void AutofillPopupBaseView::OnMouseCaptureLost() {
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.
121 // If we move off of the popup, we lose the selection.
126 void AutofillPopupBaseView::OnMouseExited(const ui::MouseEvent
& event
) {
130 void AutofillPopupBaseView::OnMouseMoved(const ui::MouseEvent
& event
) {
131 if (HitTestPoint(event
.location()))
132 SetSelection(event
.location());
137 bool AutofillPopupBaseView::OnMousePressed(const ui::MouseEvent
& event
) {
138 if (HitTestPoint(event
.location()))
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
);
158 // |this| is now deleted.
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());
186 case ui::ET_GESTURE_TAP
:
187 case ui::ET_GESTURE_SCROLL_END
:
188 if (HitTestPoint(event
->location()))
189 SetSelection(event
->location());
193 case ui::ET_GESTURE_TAP_CANCEL
:
194 case ui::ET_SCROLL_FLING_START
:
203 void AutofillPopupBaseView::SetSelection(const gfx::Point
& point
) {
205 delegate_
->SetSelectionAtPoint(point
);
208 void AutofillPopupBaseView::AcceptSelection(const gfx::Point
& point
) {
210 delegate_
->AcceptSelectionAtPoint(point
);
213 void AutofillPopupBaseView::ClearSelection() {
215 delegate_
->SelectionCleared();
218 bool AutofillPopupBaseView::ShouldHideOnOutsideClick() {
220 return delegate_
->ShouldHideOnOutsideClick();
222 // |this| instance should be in the process of being destroyed, so the return
223 // value shouldn't matter.
227 void AutofillPopupBaseView::HideController() {
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