• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 UI_VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_H_
6 #define UI_VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_H_
7 
8 #include <string>
9 
10 #include "base/basictypes.h"
11 #include "base/compiler_specific.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/strings/string16.h"
15 #include "base/timer/timer.h"
16 #include "third_party/skia/include/core/SkColor.h"
17 #include "ui/base/ime/text_input_client.h"
18 #include "ui/base/ime/text_input_type.h"
19 #include "ui/base/models/simple_menu_model.h"
20 #include "ui/base/touch/touch_editing_controller.h"
21 #include "ui/events/keycodes/keyboard_codes.h"
22 #include "ui/gfx/font_list.h"
23 #include "ui/gfx/range/range.h"
24 #include "ui/gfx/selection_model.h"
25 #include "ui/gfx/text_constants.h"
26 #include "ui/views/context_menu_controller.h"
27 #include "ui/views/controls/textfield/textfield_model.h"
28 #include "ui/views/drag_controller.h"
29 #include "ui/views/view.h"
30 
31 namespace views {
32 
33 class MenuRunner;
34 class Painter;
35 class TextfieldController;
36 
37 // A views/skia textfield implementation. No platform-specific code is used.
38 class VIEWS_EXPORT Textfield : public View,
39                                public TextfieldModel::Delegate,
40                                public ContextMenuController,
41                                public DragController,
42                                public ui::TouchEditable,
43                                public ui::TextInputClient {
44  public:
45   // The textfield's class name.
46   static const char kViewClassName[];
47 
48   // The preferred size of the padding to be used around textfield text.
49   static const int kTextPadding;
50 
51   // Returns the text cursor blink time in milliseconds, or 0 for no blinking.
52   static size_t GetCaretBlinkMs();
53 
54   Textfield();
55   virtual ~Textfield();
56 
57   // Set the controller for this textfield.
set_controller(TextfieldController * controller)58   void set_controller(TextfieldController* controller) {
59     controller_ = controller;
60   }
61 
62   // Gets/Sets whether or not the Textfield is read-only.
read_only()63   bool read_only() const { return read_only_; }
64   void SetReadOnly(bool read_only);
65 
66   // Sets the input type; displays only asterisks for TEXT_INPUT_TYPE_PASSWORD.
67   void SetTextInputType(ui::TextInputType type);
68 
69   // Gets the text currently displayed in the Textfield.
text()70   const base::string16& text() const { return model_->text(); }
71 
72   // Sets the text currently displayed in the Textfield.  This doesn't
73   // change the cursor position if the current cursor is within the
74   // new text's range, or moves the cursor to the end if the cursor is
75   // out of the new text's range.
76   void SetText(const base::string16& new_text);
77 
78   // Appends the given string to the previously-existing text in the field.
79   void AppendText(const base::string16& new_text);
80 
81   // Inserts |new_text| at the cursor position, replacing any selected text.
82   void InsertOrReplaceText(const base::string16& new_text);
83 
84   // Returns the text direction.
85   base::i18n::TextDirection GetTextDirection() const;
86 
87   // Returns the text that is currently selected.
88   base::string16 GetSelectedText() const;
89 
90   // Select the entire text range. If |reversed| is true, the range will end at
91   // the logical beginning of the text; this generally shows the leading portion
92   // of text that overflows its display area.
93   void SelectAll(bool reversed);
94 
95   // A convenience method to select the word closest to |point|.
96   void SelectWordAt(const gfx::Point& point);
97 
98   // Clears the selection within the edit field and sets the caret to the end.
99   void ClearSelection();
100 
101   // Checks if there is any selected text.
102   bool HasSelection() const;
103 
104   // Gets/sets the text color to be used when painting the Textfield.
105   // Call UseDefaultTextColor() to restore the default system color.
106   SkColor GetTextColor() const;
107   void SetTextColor(SkColor color);
108   void UseDefaultTextColor();
109 
110   // Gets/sets the background color to be used when painting the Textfield.
111   // Call UseDefaultBackgroundColor() to restore the default system color.
112   SkColor GetBackgroundColor() const;
113   void SetBackgroundColor(SkColor color);
114   void UseDefaultBackgroundColor();
115 
116   // Gets/sets the selection text color to be used when painting the Textfield.
117   // Call UseDefaultSelectionTextColor() to restore the default system color.
118   SkColor GetSelectionTextColor() const;
119   void SetSelectionTextColor(SkColor color);
120   void UseDefaultSelectionTextColor();
121 
122   // Gets/sets the selection background color to be used when painting the
123   // Textfield. Call UseDefaultSelectionBackgroundColor() to restore the default
124   // system color.
125   SkColor GetSelectionBackgroundColor() const;
126   void SetSelectionBackgroundColor(SkColor color);
127   void UseDefaultSelectionBackgroundColor();
128 
129   // Set drop shadows underneath the text.
130   void SetShadows(const gfx::ShadowValues& shadows);
131 
132   // Gets/Sets whether or not the cursor is enabled.
133   bool GetCursorEnabled() const;
134   void SetCursorEnabled(bool enabled);
135 
136   // Gets/Sets the fonts used when rendering the text within the Textfield.
137   const gfx::FontList& GetFontList() const;
138   void SetFontList(const gfx::FontList& font_list);
139 
140   // Sets the default width of the text control. See default_width_in_chars_.
set_default_width_in_chars(int default_width)141   void set_default_width_in_chars(int default_width) {
142     default_width_in_chars_ = default_width;
143   }
144 
145   // Sets the text to display when empty.
set_placeholder_text(const base::string16 & text)146   void set_placeholder_text(const base::string16& text) {
147     placeholder_text_ = text;
148   }
149   virtual base::string16 GetPlaceholderText() const;
150 
placeholder_text_color()151   SkColor placeholder_text_color() const { return placeholder_text_color_; }
set_placeholder_text_color(SkColor color)152   void set_placeholder_text_color(SkColor color) {
153     placeholder_text_color_ = color;
154   }
155 
156   // Get or set the horizontal alignment used for the button from the underlying
157   // RenderText object.
158   gfx::HorizontalAlignment GetHorizontalAlignment() const;
159   void SetHorizontalAlignment(gfx::HorizontalAlignment alignment);
160 
161   // Displays a virtual keyboard or alternate input view if enabled.
162   void ShowImeIfNeeded();
163 
164   // Returns whether or not an IME is composing text.
165   bool IsIMEComposing() const;
166 
167   // Gets the selected logical text range.
168   const gfx::Range& GetSelectedRange() const;
169 
170   // Selects the specified logical text range.
171   void SelectRange(const gfx::Range& range);
172 
173   // Gets the text selection model.
174   const gfx::SelectionModel& GetSelectionModel() const;
175 
176   // Sets the specified text selection model.
177   void SelectSelectionModel(const gfx::SelectionModel& sel);
178 
179   // Returns the current cursor position.
180   size_t GetCursorPosition() const;
181 
182   // Set the text color over the entire text or a logical character range.
183   // Empty and invalid ranges are ignored.
184   void SetColor(SkColor value);
185   void ApplyColor(SkColor value, const gfx::Range& range);
186 
187   // Set various text styles over the entire text or a logical character range.
188   // The respective |style| is applied if |value| is true, or removed if false.
189   // Empty and invalid ranges are ignored.
190   void SetStyle(gfx::TextStyle style, bool value);
191   void ApplyStyle(gfx::TextStyle style, bool value, const gfx::Range& range);
192 
193   // Clears Edit history.
194   void ClearEditHistory();
195 
196   // Set the accessible name of the text field.
197   void SetAccessibleName(const base::string16& name);
198 
199   // Performs the action associated with the specified command id.
200   void ExecuteCommand(int command_id);
201 
202   void SetFocusPainter(scoped_ptr<Painter> focus_painter);
203 
204   // Returns whether there is a drag operation originating from the textfield.
205   bool HasTextBeingDragged();
206 
207   // View overrides:
208   virtual gfx::Insets GetInsets() const OVERRIDE;
209   virtual int GetBaseline() const OVERRIDE;
210   virtual gfx::Size GetPreferredSize() const OVERRIDE;
211   virtual const char* GetClassName() const OVERRIDE;
212   virtual gfx::NativeCursor GetCursor(const ui::MouseEvent& event) OVERRIDE;
213   virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
214   virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
215   virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
216   virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE;
217   virtual ui::TextInputClient* GetTextInputClient() OVERRIDE;
218   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
219   virtual void AboutToRequestFocusFromTabTraversal(bool reverse) OVERRIDE;
220   virtual bool SkipDefaultKeyEventProcessing(
221       const ui::KeyEvent& event) OVERRIDE;
222   virtual bool GetDropFormats(
223       int* formats,
224       std::set<ui::OSExchangeData::CustomFormat>* custom_formats) OVERRIDE;
225   virtual bool CanDrop(const ui::OSExchangeData& data) OVERRIDE;
226   virtual int OnDragUpdated(const ui::DropTargetEvent& event) OVERRIDE;
227   virtual void OnDragExited() OVERRIDE;
228   virtual int OnPerformDrop(const ui::DropTargetEvent& event) OVERRIDE;
229   virtual void OnDragDone() OVERRIDE;
230   virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
231   virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
232   virtual bool GetNeedsNotificationWhenVisibleBoundsChange() const OVERRIDE;
233   virtual void OnVisibleBoundsChanged() OVERRIDE;
234   virtual void OnEnabledChanged() OVERRIDE;
235   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
236   virtual void OnFocus() OVERRIDE;
237   virtual void OnBlur() OVERRIDE;
238   virtual gfx::Point GetKeyboardContextMenuLocation() OVERRIDE;
239   virtual void OnNativeThemeChanged(const ui::NativeTheme* theme) OVERRIDE;
240 
241   // TextfieldModel::Delegate overrides:
242   virtual void OnCompositionTextConfirmedOrCleared() OVERRIDE;
243 
244   // ContextMenuController overrides:
245   virtual void ShowContextMenuForView(View* source,
246                                       const gfx::Point& point,
247                                       ui::MenuSourceType source_type) OVERRIDE;
248 
249   // DragController overrides:
250   virtual void WriteDragDataForView(View* sender,
251                                     const gfx::Point& press_pt,
252                                     ui::OSExchangeData* data) OVERRIDE;
253   virtual int GetDragOperationsForView(View* sender,
254                                        const gfx::Point& p) OVERRIDE;
255   virtual bool CanStartDragForView(View* sender,
256                                    const gfx::Point& press_pt,
257                                    const gfx::Point& p) OVERRIDE;
258 
259   // ui::TouchEditable overrides:
260   virtual void SelectRect(const gfx::Point& start,
261                           const gfx::Point& end) OVERRIDE;
262   virtual void MoveCaretTo(const gfx::Point& point) OVERRIDE;
263   virtual void GetSelectionEndPoints(gfx::Rect* p1, gfx::Rect* p2) OVERRIDE;
264   virtual gfx::Rect GetBounds() OVERRIDE;
265   virtual gfx::NativeView GetNativeView() const OVERRIDE;
266   virtual void ConvertPointToScreen(gfx::Point* point) OVERRIDE;
267   virtual void ConvertPointFromScreen(gfx::Point* point) OVERRIDE;
268   virtual bool DrawsHandles() OVERRIDE;
269   virtual void OpenContextMenu(const gfx::Point& anchor) OVERRIDE;
270   virtual void DestroyTouchSelection() OVERRIDE;
271 
272   // ui::SimpleMenuModel::Delegate overrides:
273   virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
274   virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
275   virtual bool GetAcceleratorForCommandId(
276       int command_id,
277       ui::Accelerator* accelerator) OVERRIDE;
278   virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
279 
280   // ui::TextInputClient overrides:
281   virtual void SetCompositionText(
282       const ui::CompositionText& composition) OVERRIDE;
283   virtual void ConfirmCompositionText() OVERRIDE;
284   virtual void ClearCompositionText() OVERRIDE;
285   virtual void InsertText(const base::string16& text) OVERRIDE;
286   virtual void InsertChar(base::char16 ch, int flags) OVERRIDE;
287   virtual gfx::NativeWindow GetAttachedWindow() const OVERRIDE;
288   virtual ui::TextInputType GetTextInputType() const OVERRIDE;
289   virtual ui::TextInputMode GetTextInputMode() const OVERRIDE;
290   virtual bool CanComposeInline() const OVERRIDE;
291   virtual gfx::Rect GetCaretBounds() const OVERRIDE;
292   virtual bool GetCompositionCharacterBounds(uint32 index,
293                                              gfx::Rect* rect) const OVERRIDE;
294   virtual bool HasCompositionText() const OVERRIDE;
295   virtual bool GetTextRange(gfx::Range* range) const OVERRIDE;
296   virtual bool GetCompositionTextRange(gfx::Range* range) const OVERRIDE;
297   virtual bool GetSelectionRange(gfx::Range* range) const OVERRIDE;
298   virtual bool SetSelectionRange(const gfx::Range& range) OVERRIDE;
299   virtual bool DeleteRange(const gfx::Range& range) OVERRIDE;
300   virtual bool GetTextFromRange(const gfx::Range& range,
301                                 base::string16* text) const OVERRIDE;
302   virtual void OnInputMethodChanged() OVERRIDE;
303   virtual bool ChangeTextDirectionAndLayoutAlignment(
304       base::i18n::TextDirection direction) OVERRIDE;
305   virtual void ExtendSelectionAndDelete(size_t before, size_t after) OVERRIDE;
306   virtual void EnsureCaretInRect(const gfx::Rect& rect) OVERRIDE;
307   virtual void OnCandidateWindowShown() OVERRIDE;
308   virtual void OnCandidateWindowUpdated() OVERRIDE;
309   virtual void OnCandidateWindowHidden() OVERRIDE;
310   virtual bool IsEditingCommandEnabled(int command_id) OVERRIDE;
311   virtual void ExecuteEditingCommand(int command_id) OVERRIDE;
312 
313  protected:
314   // Returns the TextfieldModel's text/cursor/selection rendering model.
315   gfx::RenderText* GetRenderText() const;
316 
last_click_location()317   gfx::Point last_click_location() const { return last_click_location_; }
318 
319   // Get the text from the selection clipboard.
320   virtual base::string16 GetSelectionClipboardText() const;
321 
322  private:
323   friend class TextfieldTestApi;
324 
325   // Handles a request to change the value of this text field from software
326   // using an accessibility API (typically automation software, screen readers
327   // don't normally use this). Sets the value and clears the selection.
328   void AccessibilitySetValue(const base::string16& new_value);
329 
330   // Updates the painted background color.
331   void UpdateBackgroundColor();
332 
333   // Does necessary updates when the text and/or cursor position changes.
334   void UpdateAfterChange(bool text_changed, bool cursor_changed);
335 
336   // A callback function to periodically update the cursor state.
337   void UpdateCursor();
338 
339   // Repaint the cursor.
340   void RepaintCursor();
341 
342   void PaintTextAndCursor(gfx::Canvas* canvas);
343 
344   // Helper function to call MoveCursorTo on the TextfieldModel.
345   void MoveCursorTo(const gfx::Point& point, bool select);
346 
347   // Helper function to update the selection on a mouse drag.
348   void SelectThroughLastDragLocation();
349 
350   // Convenience method to notify the InputMethod and TouchSelectionController.
351   void OnCaretBoundsChanged();
352 
353   // Convenience method to call TextfieldController::OnBeforeUserAction();
354   void OnBeforeUserAction();
355 
356   // Convenience method to call TextfieldController::OnAfterUserAction();
357   void OnAfterUserAction();
358 
359   // Calls |model_->Cut()| and notifies TextfieldController on success.
360   bool Cut();
361 
362   // Calls |model_->Copy()| and notifies TextfieldController on success.
363   bool Copy();
364 
365   // Calls |model_->Paste()| and calls TextfieldController::ContentsChanged()
366   // explicitly if paste succeeded.
367   bool Paste();
368 
369   // Utility function to prepare the context menu.
370   void UpdateContextMenu();
371 
372   // Tracks the mouse clicks for single/double/triple clicks.
373   void TrackMouseClicks(const ui::MouseEvent& event);
374 
375   // Returns true if the current text input type allows access by the IME.
376   bool ImeEditingAllowed() const;
377 
378   // Reveals the password character at |index| for a set duration.
379   // If |index| is -1, the existing revealed character will be reset.
380   void RevealPasswordChar(int index);
381 
382   void CreateTouchSelectionControllerAndNotifyIt();
383 
384   // Updates the selection clipboard to any non-empty text selection.
385   void UpdateSelectionClipboard() const;
386 
387   // Pastes the selection clipboard for the specified mouse event.
388   void PasteSelectionClipboard(const ui::MouseEvent& event);
389 
390   // The text model.
391   scoped_ptr<TextfieldModel> model_;
392 
393   // This is the current listener for events from this Textfield.
394   TextfieldController* controller_;
395 
396   // True if this Textfield cannot accept input and is read-only.
397   bool read_only_;
398 
399   // The default number of average characters for the width of this text field.
400   // This will be reported as the "desired size". Defaults to 0.
401   int default_width_in_chars_;
402 
403   scoped_ptr<Painter> focus_painter_;
404 
405   // Flags indicating whether various system colors should be used, and if not,
406   // what overriding color values should be used instead.
407   bool use_default_text_color_;
408   bool use_default_background_color_;
409   bool use_default_selection_text_color_;
410   bool use_default_selection_background_color_;
411   SkColor text_color_;
412   SkColor background_color_;
413   SkColor selection_text_color_;
414   SkColor selection_background_color_;
415 
416   // Text to display when empty.
417   base::string16 placeholder_text_;
418 
419   // Placeholder text color.
420   SkColor placeholder_text_color_;
421 
422   // The accessible name of the text field.
423   base::string16 accessible_name_;
424 
425   // The input type of this text field.
426   ui::TextInputType text_input_type_;
427 
428   // The duration and timer to reveal the last typed password character.
429   base::TimeDelta password_reveal_duration_;
430   base::OneShotTimer<Textfield> password_reveal_timer_;
431 
432   // Tracks whether a user action is being performed; i.e. OnBeforeUserAction()
433   // has been called, but OnAfterUserAction() has not yet been called.
434   bool performing_user_action_;
435 
436   // True if InputMethod::CancelComposition() should not be called.
437   bool skip_input_method_cancel_composition_;
438 
439   // The text editing cursor repaint timer and visibility.
440   base::RepeatingTimer<Textfield> cursor_repaint_timer_;
441   bool cursor_visible_;
442 
443   // The drop cursor is a visual cue for where dragged text will be dropped.
444   bool drop_cursor_visible_;
445   gfx::SelectionModel drop_cursor_position_;
446 
447   // Is the user potentially dragging and dropping from this view?
448   bool initiating_drag_;
449 
450   // A timer and point used to modify the selection when dragging.
451   base::RepeatingTimer<Textfield> drag_selection_timer_;
452   gfx::Point last_drag_location_;
453 
454   // State variables used to track double and triple clicks.
455   size_t aggregated_clicks_;
456   base::TimeDelta last_click_time_;
457   gfx::Point last_click_location_;
458   gfx::Range double_click_word_;
459 
460   scoped_ptr<ui::TouchSelectionController> touch_selection_controller_;
461 
462   // Used to track touch drag starting location and offset to enable touch
463   // scrolling.
464   gfx::Point drag_start_location_;
465   int drag_start_display_offset_;
466 
467   // Tracks if touch editing handles are hidden because user has started
468   // scrolling. If |true|, handles are shown after scrolling ends.
469   bool touch_handles_hidden_due_to_scroll_;
470 
471   // Context menu related members.
472   scoped_ptr<ui::SimpleMenuModel> context_menu_contents_;
473   scoped_ptr<views::MenuRunner> context_menu_runner_;
474 
475   // Used to bind callback functions to this object.
476   base::WeakPtrFactory<Textfield> weak_ptr_factory_;
477 
478   DISALLOW_COPY_AND_ASSIGN(Textfield);
479 };
480 
481 }  // namespace views
482 
483 #endif  // UI_VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_H_
484