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