autofill_popup_controller_impl.h revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
1// Copyright (c) 2012 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#ifndef CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_POPUP_CONTROLLER_IMPL_H_
6#define CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_POPUP_CONTROLLER_IMPL_H_
7
8#include "base/gtest_prod_util.h"
9#include "base/i18n/rtl.h"
10#include "base/memory/weak_ptr.h"
11#include "base/strings/string16.h"
12#include "chrome/browser/ui/autofill/autofill_popup_controller.h"
13#include "content/public/browser/keyboard_listener.h"
14#include "ui/gfx/font.h"
15#include "ui/gfx/rect.h"
16#include "ui/gfx/rect_f.h"
17
18namespace gfx {
19class Display;
20}
21
22namespace ui {
23class KeyEvent;
24}
25
26namespace autofill {
27
28class AutofillPopupDelegate;
29class AutofillPopupView;
30
31// This class is a controller for an AutofillPopupView. It implements
32// AutofillPopupController to allow calls from AutofillPopupView. The
33// other, public functions are available to its instantiator.
34class AutofillPopupControllerImpl : public AutofillPopupController,
35                                    public content::KeyboardListener {
36 public:
37  // Creates a new |AutofillPopupControllerImpl|, or reuses |previous| if
38  // the construction arguments are the same. |previous| may be invalidated by
39  // this call.
40  static base::WeakPtr<AutofillPopupControllerImpl> GetOrCreate(
41      base::WeakPtr<AutofillPopupControllerImpl> previous,
42      base::WeakPtr<AutofillPopupDelegate> delegate,
43      gfx::NativeView container_view,
44      const gfx::RectF& element_bounds,
45      base::i18n::TextDirection text_direction);
46
47  // Shows the popup, or updates the existing popup with the given values.
48  void Show(const std::vector<string16>& names,
49            const std::vector<string16>& subtexts,
50            const std::vector<string16>& icons,
51            const std::vector<int>& identifiers);
52
53  // Updates the data list values currently shown with the popup.
54  void UpdateDataListValues(const std::vector<base::string16>& values,
55                            const std::vector<base::string16>& labels);
56
57  // Hides the popup and destroys the controller. This also invalidates
58  // |delegate_|.
59  virtual void Hide() OVERRIDE;
60
61  // Invoked when the view was destroyed by by someone other than this class.
62  virtual void ViewDestroyed() OVERRIDE;
63
64  // KeyboardListener implementation.
65  virtual bool HandleKeyPressEvent(
66      const content::NativeWebKeyboardEvent& event) OVERRIDE;
67
68 protected:
69  FRIEND_TEST_ALL_PREFIXES(AutofillExternalDelegateBrowserTest,
70                           CloseWidgetAndNoLeaking);
71  FRIEND_TEST_ALL_PREFIXES(AutofillPopupControllerUnitTest,
72                           ProperlyResetController);
73
74  AutofillPopupControllerImpl(base::WeakPtr<AutofillPopupDelegate> delegate,
75                              gfx::NativeView container_view,
76                              const gfx::RectF& element_bounds,
77                              base::i18n::TextDirection text_direction);
78  virtual ~AutofillPopupControllerImpl();
79
80  // AutofillPopupController implementation.
81  virtual void UpdateBoundsAndRedrawPopup() OVERRIDE;
82  virtual void MouseHovered(int x, int y) OVERRIDE;
83  virtual void MouseClicked(int x, int y) OVERRIDE;
84  virtual void MouseExitedPopup() OVERRIDE;
85  virtual void AcceptSuggestion(size_t index) OVERRIDE;
86  virtual int GetIconResourceID(const string16& resource_name) OVERRIDE;
87  virtual bool CanDelete(size_t index) const OVERRIDE;
88  virtual bool IsWarning(size_t index) const OVERRIDE;
89  virtual gfx::Rect GetRowBounds(size_t index) OVERRIDE;
90  virtual void SetPopupBounds(const gfx::Rect& bounds) OVERRIDE;
91  virtual const gfx::Rect& popup_bounds() const OVERRIDE;
92  virtual gfx::NativeView container_view() const OVERRIDE;
93  virtual const gfx::RectF& element_bounds() const OVERRIDE;
94  virtual bool IsRTL() const OVERRIDE;
95
96  virtual const std::vector<string16>& names() const OVERRIDE;
97  virtual const std::vector<string16>& subtexts() const OVERRIDE;
98  virtual const std::vector<string16>& icons() const OVERRIDE;
99  virtual const std::vector<int>& identifiers() const OVERRIDE;
100#if !defined(OS_ANDROID)
101  virtual const gfx::Font& GetNameFontForRow(size_t index) const OVERRIDE;
102  virtual const gfx::Font& subtext_font() const OVERRIDE;
103#endif
104  virtual int selected_line() const OVERRIDE;
105
106  // Change which line is currently selected by the user.
107  void SetSelectedLine(int selected_line);
108
109  // Increase the selected line by 1, properly handling wrapping.
110  void SelectNextLine();
111
112  // Decrease the selected line by 1, properly handling wrapping.
113  void SelectPreviousLine();
114
115  // The user has choosen the selected line.
116  bool AcceptSelectedLine();
117
118  // The user has removed a suggestion.
119  bool RemoveSelectedLine();
120
121  // Convert a y-coordinate to the closest line.
122  int LineFromY(int y);
123
124  // Returns the height of a row depending on its type.
125  int GetRowHeightFromId(int identifier) const;
126
127  // Returns true if the given id refers to an element that can be accepted.
128  bool CanAccept(int id);
129
130  // Returns true if the popup still has non-options entries to show the user.
131  bool HasSuggestions();
132
133  // Set the Autofill entry values. Exposed to allow tests to set these values
134  // without showing the popup.
135  void SetValues(const std::vector<string16>& names,
136                 const std::vector<string16>& subtexts,
137                 const std::vector<string16>& icons,
138                 const std::vector<int>& identifier);
139
140  AutofillPopupView* view() { return view_; }
141
142  // |view_| pass throughs (virtual for testing).
143  virtual void ShowView();
144  virtual void InvalidateRow(size_t row);
145
146  // Protected so tests can access.
147#if !defined(OS_ANDROID)
148  // Calculates the desired width of the popup based on its contents.
149  int GetDesiredPopupWidth() const;
150
151  // Calculates the desired height of the popup based on its contents.
152  int GetDesiredPopupHeight() const;
153
154  // Calculate the width of the row, excluding all the text. This provides
155  // the size of the row that won't be reducible (since all the text can be
156  // elided if there isn't enough space).
157  int RowWidthWithoutText(int row) const;
158#endif
159
160  base::WeakPtr<AutofillPopupControllerImpl> GetWeakPtr();
161
162 private:
163  // Clear the internal state of the controller. This is needed to ensure that
164  // when the popup is reused it doesn't leak values between uses.
165  void ClearState();
166
167  const gfx::Rect RoundedElementBounds() const;
168#if !defined(OS_ANDROID)
169  // Calculates and sets the bounds of the popup, including placing it properly
170  // to prevent it from going off the screen.
171  void UpdatePopupBounds();
172#endif
173
174  // A helper function to get the display closest to the given point (virtual
175  // for testing).
176  virtual gfx::Display GetDisplayNearestPoint(const gfx::Point& point) const;
177
178  // Calculates the width of the popup and the x position of it. These values
179  // will stay on the screen.
180  std::pair<int, int> CalculatePopupXAndWidth(
181      const gfx::Display& left_display,
182      const gfx::Display& right_display,
183      int popup_required_width) const;
184
185  // Calculates the height of the popup and the y position of it. These values
186  // will stay on the screen.
187  std::pair<int, int> CalculatePopupYAndHeight(
188      const gfx::Display& top_display,
189      const gfx::Display& bottom_display,
190      int popup_required_height) const;
191
192  AutofillPopupView* view_;  // Weak reference.
193  base::WeakPtr<AutofillPopupDelegate> delegate_;
194  gfx::NativeView container_view_;  // Weak reference.
195
196  // The bounds of the text element that is the focus of the Autofill.
197  // These coordinates are in screen space.
198  const gfx::RectF element_bounds_;
199
200  // The bounds of the Autofill popup.
201  gfx::Rect popup_bounds_;
202
203  // The text direction of the popup.
204  base::i18n::TextDirection text_direction_;
205
206  // The current Autofill query values.
207  std::vector<string16> names_;
208  std::vector<string16> subtexts_;
209  std::vector<string16> icons_;
210  std::vector<int> identifiers_;
211
212  // Since names_ can be elided to ensure that it fits on the screen, we need to
213  // keep an unelided copy of the names to be able to pass to the delegate.
214  std::vector<string16> full_names_;
215
216#if !defined(OS_ANDROID)
217  // The fonts for the popup text.
218  gfx::Font name_font_;
219  gfx::Font subtext_font_;
220  gfx::Font warning_font_;
221#endif
222
223  // The line that is currently selected by the user.
224  // |kNoSelection| indicates that no line is currently selected.
225  int selected_line_;
226
227  base::WeakPtrFactory<AutofillPopupControllerImpl> weak_ptr_factory_;
228};
229
230}  // namespace autofill
231
232#endif  // CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_POPUP_CONTROLLER_IMPL_H_
233