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 // The preferred size of the padding to be used around textfield text.
49 static const int kTextPadding
;
51 // Returns the text cursor blink time in milliseconds, or 0 for no blinking.
52 static size_t GetCaretBlinkMs();
55 ~Textfield() override
;
57 // Set the controller for this textfield.
58 void set_controller(TextfieldController
* controller
) {
59 controller_
= controller
;
62 // Gets/Sets whether or not the Textfield is read-only.
63 bool read_only() const { return read_only_
; }
64 void SetReadOnly(bool read_only
);
66 // Sets the input type; displays only asterisks for TEXT_INPUT_TYPE_PASSWORD.
67 void SetTextInputType(ui::TextInputType type
);
69 // Sets the input flags so that the system input methods can turn on/off some
70 // features. The flags is the bit map of ui::TextInputFlags.
71 void SetTextInputFlags(int flags
);
73 // Gets the text currently displayed in the Textfield.
74 const base::string16
& text() const { return model_
->text(); }
76 // Sets the text currently displayed in the Textfield. This doesn't
77 // change the cursor position if the current cursor is within the
78 // new text's range, or moves the cursor to the end if the cursor is
79 // out of the new text's range.
80 void SetText(const base::string16
& new_text
);
82 // Appends the given string to the previously-existing text in the field.
83 void AppendText(const base::string16
& new_text
);
85 // Inserts |new_text| at the cursor position, replacing any selected text.
86 void InsertOrReplaceText(const base::string16
& new_text
);
88 // Returns the text direction.
89 base::i18n::TextDirection
GetTextDirection() const;
91 // Returns the text that is currently selected.
92 base::string16
GetSelectedText() const;
94 // Select the entire text range. If |reversed| is true, the range will end at
95 // the logical beginning of the text; this generally shows the leading portion
96 // of text that overflows its display area.
97 void SelectAll(bool reversed
);
99 // A convenience method to select the word closest to |point|.
100 void SelectWordAt(const gfx::Point
& point
);
102 // Clears the selection within the edit field and sets the caret to the end.
103 void ClearSelection();
105 // Checks if there is any selected text.
106 bool HasSelection() const;
108 // Gets/sets the text color to be used when painting the Textfield.
109 // Call UseDefaultTextColor() to restore the default system color.
110 SkColor
GetTextColor() const;
111 void SetTextColor(SkColor color
);
112 void UseDefaultTextColor();
114 // Gets/sets the background color to be used when painting the Textfield.
115 // Call UseDefaultBackgroundColor() to restore the default system color.
116 SkColor
GetBackgroundColor() const;
117 void SetBackgroundColor(SkColor color
);
118 void UseDefaultBackgroundColor();
120 // Gets/sets the selection text color to be used when painting the Textfield.
121 // Call UseDefaultSelectionTextColor() to restore the default system color.
122 SkColor
GetSelectionTextColor() const;
123 void SetSelectionTextColor(SkColor color
);
124 void UseDefaultSelectionTextColor();
126 // Gets/sets the selection background color to be used when painting the
127 // Textfield. Call UseDefaultSelectionBackgroundColor() to restore the default
129 SkColor
GetSelectionBackgroundColor() const;
130 void SetSelectionBackgroundColor(SkColor color
);
131 void UseDefaultSelectionBackgroundColor();
133 // Set drop shadows underneath the text.
134 void SetShadows(const gfx::ShadowValues
& shadows
);
136 // Gets/Sets whether or not the cursor is enabled.
137 bool GetCursorEnabled() const;
138 void SetCursorEnabled(bool enabled
);
140 // Gets/Sets the fonts used when rendering the text within the Textfield.
141 const gfx::FontList
& GetFontList() const;
142 void SetFontList(const gfx::FontList
& font_list
);
144 // Sets the default width of the text control. See default_width_in_chars_.
145 void set_default_width_in_chars(int default_width
) {
146 default_width_in_chars_
= default_width
;
149 // Sets the text to display when empty.
150 void set_placeholder_text(const base::string16
& text
) {
151 placeholder_text_
= text
;
153 virtual base::string16
GetPlaceholderText() const;
155 SkColor
placeholder_text_color() const { return placeholder_text_color_
; }
156 void set_placeholder_text_color(SkColor color
) {
157 placeholder_text_color_
= color
;
160 // Get or set the horizontal alignment used for the button from the underlying
161 // RenderText object.
162 gfx::HorizontalAlignment
GetHorizontalAlignment() const;
163 void SetHorizontalAlignment(gfx::HorizontalAlignment alignment
);
165 // Displays a virtual keyboard or alternate input view if enabled.
166 void ShowImeIfNeeded();
168 // Returns whether or not an IME is composing text.
169 bool IsIMEComposing() const;
171 // Gets the selected logical text range.
172 const gfx::Range
& GetSelectedRange() const;
174 // Selects the specified logical text range.
175 void SelectRange(const gfx::Range
& range
);
177 // Gets the text selection model.
178 const gfx::SelectionModel
& GetSelectionModel() const;
180 // Sets the specified text selection model.
181 void SelectSelectionModel(const gfx::SelectionModel
& sel
);
183 // Returns the current cursor position.
184 size_t GetCursorPosition() const;
186 // Set the text color over the entire text or a logical character range.
187 // Empty and invalid ranges are ignored.
188 void SetColor(SkColor value
);
189 void ApplyColor(SkColor value
, const gfx::Range
& range
);
191 // Set various text styles over the entire text or a logical character range.
192 // The respective |style| is applied if |value| is true, or removed if false.
193 // Empty and invalid ranges are ignored.
194 void SetStyle(gfx::TextStyle style
, bool value
);
195 void ApplyStyle(gfx::TextStyle style
, bool value
, const gfx::Range
& range
);
197 // Clears Edit history.
198 void ClearEditHistory();
200 // Set the accessible name of the text field.
201 void SetAccessibleName(const base::string16
& name
);
203 // Performs the action associated with the specified command id.
204 void ExecuteCommand(int command_id
);
206 void SetFocusPainter(scoped_ptr
<Painter
> focus_painter
);
208 // Returns whether there is a drag operation originating from the textfield.
209 bool HasTextBeingDragged();
212 gfx::Insets
GetInsets() const override
;
213 int GetBaseline() const override
;
214 gfx::Size
GetPreferredSize() const override
;
215 const char* GetClassName() const override
;
216 gfx::NativeCursor
GetCursor(const ui::MouseEvent
& event
) override
;
217 bool OnMousePressed(const ui::MouseEvent
& event
) override
;
218 bool OnMouseDragged(const ui::MouseEvent
& event
) override
;
219 void OnMouseReleased(const ui::MouseEvent
& event
) override
;
220 bool OnKeyPressed(const ui::KeyEvent
& event
) override
;
221 void OnGestureEvent(ui::GestureEvent
* event
) override
;
222 bool AcceleratorPressed(const ui::Accelerator
& accelerator
) override
;
223 bool CanHandleAccelerators() const override
;
224 void AboutToRequestFocusFromTabTraversal(bool reverse
) override
;
225 bool SkipDefaultKeyEventProcessing(const ui::KeyEvent
& event
) override
;
228 std::set
<ui::OSExchangeData::CustomFormat
>* custom_formats
) override
;
229 bool CanDrop(const ui::OSExchangeData
& data
) override
;
230 int OnDragUpdated(const ui::DropTargetEvent
& event
) override
;
231 void OnDragExited() override
;
232 int OnPerformDrop(const ui::DropTargetEvent
& event
) override
;
233 void OnDragDone() override
;
234 void GetAccessibleState(ui::AXViewState
* state
) override
;
235 void OnBoundsChanged(const gfx::Rect
& previous_bounds
) override
;
236 bool GetNeedsNotificationWhenVisibleBoundsChange() const override
;
237 void OnVisibleBoundsChanged() override
;
238 void OnEnabledChanged() override
;
239 void OnPaint(gfx::Canvas
* canvas
) override
;
240 void OnFocus() override
;
241 void OnBlur() override
;
242 gfx::Point
GetKeyboardContextMenuLocation() override
;
243 void OnNativeThemeChanged(const ui::NativeTheme
* theme
) override
;
245 // TextfieldModel::Delegate overrides:
246 void OnCompositionTextConfirmedOrCleared() override
;
248 // ContextMenuController overrides:
249 void ShowContextMenuForView(View
* source
,
250 const gfx::Point
& point
,
251 ui::MenuSourceType source_type
) override
;
253 // DragController overrides:
254 void WriteDragDataForView(View
* sender
,
255 const gfx::Point
& press_pt
,
256 ui::OSExchangeData
* data
) override
;
257 int GetDragOperationsForView(View
* sender
, const gfx::Point
& p
) override
;
258 bool CanStartDragForView(View
* sender
,
259 const gfx::Point
& press_pt
,
260 const gfx::Point
& p
) override
;
262 // ui::TouchEditable overrides:
263 void SelectRect(const gfx::Point
& start
, const gfx::Point
& end
) override
;
264 void MoveCaretTo(const gfx::Point
& point
) override
;
265 void GetSelectionEndPoints(ui::SelectionBound
* anchor
,
266 ui::SelectionBound
* focus
) override
;
267 gfx::Rect
GetBounds() override
;
268 gfx::NativeView
GetNativeView() const override
;
269 void ConvertPointToScreen(gfx::Point
* point
) override
;
270 void ConvertPointFromScreen(gfx::Point
* point
) override
;
271 bool DrawsHandles() override
;
272 void OpenContextMenu(const gfx::Point
& anchor
) override
;
273 void DestroyTouchSelection() override
;
275 // ui::SimpleMenuModel::Delegate overrides:
276 bool IsCommandIdChecked(int command_id
) const override
;
277 bool IsCommandIdEnabled(int command_id
) const override
;
278 bool GetAcceleratorForCommandId(int command_id
,
279 ui::Accelerator
* accelerator
) override
;
280 void ExecuteCommand(int command_id
, int event_flags
) override
;
282 // ui::TextInputClient overrides:
283 void SetCompositionText(const ui::CompositionText
& composition
) override
;
284 void ConfirmCompositionText() override
;
285 void ClearCompositionText() override
;
286 void InsertText(const base::string16
& text
) override
;
287 void InsertChar(base::char16 ch
, int flags
) override
;
288 ui::TextInputType
GetTextInputType() const override
;
289 ui::TextInputMode
GetTextInputMode() const override
;
290 int GetTextInputFlags() const override
;
291 bool CanComposeInline() const override
;
292 gfx::Rect
GetCaretBounds() const override
;
293 bool GetCompositionCharacterBounds(uint32 index
,
294 gfx::Rect
* rect
) const override
;
295 bool HasCompositionText() const override
;
296 bool GetTextRange(gfx::Range
* range
) const override
;
297 bool GetCompositionTextRange(gfx::Range
* range
) const override
;
298 bool GetSelectionRange(gfx::Range
* range
) const override
;
299 bool SetSelectionRange(const gfx::Range
& range
) override
;
300 bool DeleteRange(const gfx::Range
& range
) override
;
301 bool GetTextFromRange(const gfx::Range
& range
,
302 base::string16
* text
) const override
;
303 void OnInputMethodChanged() override
;
304 bool ChangeTextDirectionAndLayoutAlignment(
305 base::i18n::TextDirection direction
) override
;
306 void ExtendSelectionAndDelete(size_t before
, size_t after
) override
;
307 void EnsureCaretInRect(const gfx::Rect
& rect
) override
;
308 bool IsEditCommandEnabled(int command_id
) override
;
309 void SetEditCommandForNextKeyEvent(int command_id
) override
;
312 // Inserts or appends a character in response to an IME operation.
313 virtual void DoInsertChar(base::char16 ch
);
315 // Returns the TextfieldModel's text/cursor/selection rendering model.
316 gfx::RenderText
* GetRenderText() const;
318 gfx::Point
last_click_location() const { return last_click_location_
; }
320 // Get the text from the selection clipboard.
321 virtual base::string16
GetSelectionClipboardText() const;
324 friend class TextfieldTestApi
;
326 // Handles a request to change the value of this text field from software
327 // using an accessibility API (typically automation software, screen readers
328 // don't normally use this). Sets the value and clears the selection.
329 void AccessibilitySetValue(const base::string16
& new_value
);
331 // Updates the painted background color.
332 void UpdateBackgroundColor();
334 // Does necessary updates when the text and/or cursor position changes.
335 void UpdateAfterChange(bool text_changed
, bool cursor_changed
);
337 // A callback function to periodically update the cursor state.
340 // Repaint the cursor.
341 void RepaintCursor();
343 void PaintTextAndCursor(gfx::Canvas
* canvas
);
345 // Helper function to call MoveCursorTo on the TextfieldModel.
346 void MoveCursorTo(const gfx::Point
& point
, bool select
);
348 // Helper function to update the selection on a mouse drag.
349 void SelectThroughLastDragLocation();
351 // Convenience method to notify the InputMethod and TouchSelectionController.
352 void OnCaretBoundsChanged();
354 // Convenience method to call TextfieldController::OnBeforeUserAction();
355 void OnBeforeUserAction();
357 // Convenience method to call TextfieldController::OnAfterUserAction();
358 void OnAfterUserAction();
360 // Calls |model_->Cut()| and notifies TextfieldController on success.
363 // Calls |model_->Copy()| and notifies TextfieldController on success.
366 // Calls |model_->Paste()| and calls TextfieldController::ContentsChanged()
367 // explicitly if paste succeeded.
370 // Utility function to prepare the context menu.
371 void UpdateContextMenu();
373 // Tracks the mouse clicks for single/double/triple clicks.
374 void TrackMouseClicks(const ui::MouseEvent
& event
);
376 // Returns true if the current text input type allows access by the IME.
377 bool ImeEditingAllowed() const;
379 // Reveals the password character at |index| for a set duration.
380 // If |index| is -1, the existing revealed character will be reset.
381 void RevealPasswordChar(int index
);
383 void CreateTouchSelectionControllerAndNotifyIt();
385 // Updates the selection clipboard to any non-empty text selection.
386 void UpdateSelectionClipboard() const;
388 // Pastes the selection clipboard for the specified mouse event.
389 void PasteSelectionClipboard(const ui::MouseEvent
& event
);
392 scoped_ptr
<TextfieldModel
> model_
;
394 // This is the current listener for events from this Textfield.
395 TextfieldController
* controller_
;
397 // If non-zero, an edit command to execute on the next key event. When set,
398 // the key event is still passed to |controller_|, but otherwise ignored in
399 // favor of the edit command. Set via SetEditCommandForNextKeyEvent() during
400 // dispatch of that key event (see comment in TextInputClient).
401 int scheduled_edit_command_
;
403 // True if this Textfield cannot accept input and is read-only.
406 // The default number of average characters for the width of this text field.
407 // This will be reported as the "desired size". Defaults to 0.
408 int default_width_in_chars_
;
410 scoped_ptr
<Painter
> focus_painter_
;
412 // Flags indicating whether various system colors should be used, and if not,
413 // what overriding color values should be used instead.
414 bool use_default_text_color_
;
415 bool use_default_background_color_
;
416 bool use_default_selection_text_color_
;
417 bool use_default_selection_background_color_
;
419 SkColor background_color_
;
420 SkColor selection_text_color_
;
421 SkColor selection_background_color_
;
423 // Text to display when empty.
424 base::string16 placeholder_text_
;
426 // Placeholder text color.
427 SkColor placeholder_text_color_
;
429 // The accessible name of the text field.
430 base::string16 accessible_name_
;
432 // The input type of this text field.
433 ui::TextInputType text_input_type_
;
435 // The input flags of this text field.
436 int text_input_flags_
;
438 // The duration and timer to reveal the last typed password character.
439 base::TimeDelta password_reveal_duration_
;
440 base::OneShotTimer
<Textfield
> password_reveal_timer_
;
442 // Tracks whether a user action is being performed; i.e. OnBeforeUserAction()
443 // has been called, but OnAfterUserAction() has not yet been called.
444 bool performing_user_action_
;
446 // True if InputMethod::CancelComposition() should not be called.
447 bool skip_input_method_cancel_composition_
;
449 // The text editing cursor repaint timer and visibility.
450 base::RepeatingTimer
<Textfield
> cursor_repaint_timer_
;
451 bool cursor_visible_
;
453 // The drop cursor is a visual cue for where dragged text will be dropped.
454 bool drop_cursor_visible_
;
455 gfx::SelectionModel drop_cursor_position_
;
457 // Is the user potentially dragging and dropping from this view?
458 bool initiating_drag_
;
460 // A timer and point used to modify the selection when dragging.
461 base::RepeatingTimer
<Textfield
> drag_selection_timer_
;
462 gfx::Point last_drag_location_
;
464 // State variables used to track double and triple clicks.
465 size_t aggregated_clicks_
;
466 base::TimeDelta last_click_time_
;
467 gfx::Point last_click_location_
;
468 gfx::Range double_click_word_
;
470 scoped_ptr
<ui::TouchEditingControllerDeprecated
> touch_selection_controller_
;
472 // Used to track touch drag starting location and offset to enable touch
474 gfx::Point drag_start_location_
;
475 int drag_start_display_offset_
;
477 // Tracks if touch editing handles are hidden because user has started
478 // scrolling. If |true|, handles are shown after scrolling ends.
479 bool touch_handles_hidden_due_to_scroll_
;
481 // Context menu related members.
482 scoped_ptr
<ui::SimpleMenuModel
> context_menu_contents_
;
483 scoped_ptr
<views::MenuRunner
> context_menu_runner_
;
485 // Used to bind callback functions to this object.
486 base::WeakPtrFactory
<Textfield
> weak_ptr_factory_
;
488 DISALLOW_COPY_AND_ASSIGN(Textfield
);
493 #endif // UI_VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_H_