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