Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(302)

Side by Side Diff: views/controls/textfield/textfield_views_model.h

Issue 7265011: RenderText API Outline. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Almost at parity with the current implementation. Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_VIEWS_MODEL_H_ 5 #ifndef VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_VIEWS_MODEL_H_
6 #define VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_VIEWS_MODEL_H_ 6 #define VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_VIEWS_MODEL_H_
7 #pragma once 7 #pragma once
8 8
9 #include <list> 9 #include <list>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/gtest_prod_util.h" 12 #include "base/gtest_prod_util.h"
13 #include "base/string16.h" 13 #include "base/string16.h"
14 #include "third_party/skia/include/core/SkColor.h" 14 #include "third_party/skia/include/core/SkColor.h"
15 #include "ui/base/ime/composition_text.h" 15 #include "ui/base/ime/composition_text.h"
16 #include "ui/gfx/rect.h" 16 #include "ui/gfx/rect.h"
17 17
18 namespace gfx { 18 namespace gfx {
19 class Canvas;
19 class Font; 20 class Font;
21 class RenderText;
22 struct StyleRange;
20 } // namespace gfx 23 } // namespace gfx
21 24
22 namespace ui { 25 namespace ui {
23 class Range; 26 class Range;
24 } // namespace ui 27 } // namespace ui
25 28
26 namespace views { 29 namespace views {
27 30
28 class TextStyle;
29 typedef std::vector<TextStyle*> TextStyles;
30
31 namespace internal { 31 namespace internal {
32 // Internal Edit class that keeps track of edits for undo/redo. 32 // Internal Edit class that keeps track of edits for undo/redo.
33 class Edit; 33 class Edit;
34 34
35 struct TextStyleRange;
36
37 // C++ doesn't allow forward decl enum, so let's define here. 35 // C++ doesn't allow forward decl enum, so let's define here.
38 enum MergeType { 36 enum MergeType {
39 // The edit should not be merged with next edit. It still may 37 // The edit should not be merged with next edit. It still may
40 // be merged with an edit with MERGE_WITH_PREVIOUS. 38 // be merged with an edit with MERGE_WITH_PREVIOUS.
41 DO_NOT_MERGE, 39 DO_NOT_MERGE,
42 // The edit can be merged with next edit when possible. 40 // The edit can be merged with next edit when possible.
43 MERGEABLE, 41 MERGEABLE,
44 // Does the edit have to be merged with previous edit? 42 // Does the edit have to be merged with previous edit?
45 // This forces the merge even if the previous edit is marked 43 // This forces the merge even if the previous edit is marked
46 // as DO_NOT_MERGE. 44 // as DO_NOT_MERGE.
47 MERGE_WITH_PREVIOUS, 45 MERGE_WITH_PREVIOUS,
48 }; 46 };
49 47
50 } // namespace internal 48 } // namespace internal
51 49
52 typedef std::vector<internal::TextStyleRange*> TextStyleRanges; 50 // TODO(msw): Transition TexfieldViewsModel to a more Editor-like role?
53 51
54 // A model that represents a text content for TextfieldViews. 52 // A model that represents a text content for TextfieldViews.
55 // It supports editing, selection and cursor manipulation. 53 // It supports editing, selection and cursor manipulation.
56 class TextfieldViewsModel { 54 class TextfieldViewsModel {
57 public: 55 public:
58 56
59 // Delegate interface implemented by the textfield view class to provided 57 // Delegate interface implemented by the textfield view class to provided
60 // additional functionalities required by the model. 58 // additional functionalities required by the model.
61 class Delegate { 59 class Delegate {
62 public: 60 public:
63 // Called when the current composition text is confirmed or cleared. 61 // Called when the current composition text is confirmed or cleared.
64 virtual void OnCompositionTextConfirmedOrCleared() = 0; 62 virtual void OnCompositionTextConfirmedOrCleared() = 0;
65 63
66 protected: 64 protected:
67 virtual ~Delegate(); 65 virtual ~Delegate();
68 }; 66 };
69 67
70 explicit TextfieldViewsModel(Delegate* delegate); 68 explicit TextfieldViewsModel(Delegate* delegate);
71 virtual ~TextfieldViewsModel(); 69 virtual ~TextfieldViewsModel();
72 70
73 // Text fragment info. Used to draw selected text.
74 // We may replace this with TextAttribute class
75 // in the future to support multi-color text
76 // for omnibox.
77 struct TextFragment {
78 TextFragment(size_t start, size_t end, const views::TextStyle* s)
79 : range(start, end), style(s) {
80 }
81 // The start and end position of text fragment.
82 ui::Range range;
83 const TextStyle* style;
84 };
85 typedef std::vector<TextFragment> TextFragments;
86
87 // Gets the text element info.
88 void GetFragments(TextFragments* elements);
89
90 void set_is_password(bool is_password) { 71 void set_is_password(bool is_password) {
91 is_password_ = is_password; 72 is_password_ = is_password;
92 } 73 }
93 const string16& text() const { return text_; }
94 74
95 // Edit related methods. 75 // Edit related methods.
96 76
97 // Sest the text. Returns true if the text has been modified. The 77 const string16& GetText() const;
78 // Sets the text. Returns true if the text has been modified. The
98 // current composition text will be confirmed first. Setting 79 // current composition text will be confirmed first. Setting
99 // the same text will not add edit history because it's not user 80 // the same text will not add edit history because it's not user
100 // visible change nor user-initiated change. This allow a client 81 // visible change nor user-initiated change. This allow a client
101 // code to set the same text multiple times without worrying about 82 // code to set the same text multiple times without worrying about
102 // messing edit history. 83 // messing edit history.
103 bool SetText(const string16& text); 84 bool SetText(const string16& text);
104 85
86 gfx::RenderText* get_render_text() { return render_text_; }
87
105 // Inserts given |text| at the current cursor position. 88 // Inserts given |text| at the current cursor position.
106 // The current composition text will be cleared. 89 // The current composition text will be cleared.
107 void InsertText(const string16& text) { 90 void InsertText(const string16& text) {
108 InsertTextInternal(text, false); 91 InsertTextInternal(text, false);
109 } 92 }
110 93
111 // Inserts a character at the current cursor position. 94 // Inserts a character at the current cursor position.
112 void InsertChar(char16 c) { 95 void InsertChar(char16 c) {
113 InsertTextInternal(string16(&c, 1), true); 96 InsertTextInternal(string16(&c, 1), true);
114 } 97 }
(...skipping 21 matching lines...) Expand all
136 119
137 // Deletes the first character before the current cursor position (as if, the 120 // Deletes the first character before the current cursor position (as if, the
138 // the user has pressed backspace key in the textfield). Returns true if 121 // the user has pressed backspace key in the textfield). Returns true if
139 // the removal is successful. 122 // the removal is successful.
140 // If there is composition text, it'll be deleted instead. 123 // If there is composition text, it'll be deleted instead.
141 bool Backspace(); 124 bool Backspace();
142 125
143 // Cursor related methods. 126 // Cursor related methods.
144 127
145 // Returns the current cursor position. 128 // Returns the current cursor position.
146 size_t cursor_pos() const { return cursor_pos_; } 129 size_t GetCursorPosition() const;
147 130
148 // Moves the cursor left by one position (as if, the user has pressed the left 131 // Moves the cursor left by one position (as if, the user has pressed the left
149 // arrow key). If |select| is true, it updates the selection accordingly. 132 // arrow key). If |select| is true, it updates the selection accordingly.
150 // The current composition text will be confirmed. 133 // The current composition text will be confirmed.
151 void MoveCursorLeft(bool select); 134 void MoveCursorLeft(bool select);
152 135
153 // Moves the cursor right by one position (as if, the user has pressed the 136 // Moves the cursor right by one position (as if, the user has pressed the
154 // right arrow key). If |select| is true, it updates the selection 137 // right arrow key). If |select| is true, it updates the selection
155 // accordingly. 138 // accordingly.
156 // The current composition text will be confirmed. 139 // The current composition text will be confirmed.
157 void MoveCursorRight(bool select); 140 void MoveCursorRight(bool select);
158 141
159 // Moves the cursor left by one word (word boundry is defined by space). 142 // Moves the cursor left by one word (word boundry is defined by space).
160 // If |select| is true, it updates the selection accordingly. 143 // If |select| is true, it updates the selection accordingly.
161 // The current composition text will be confirmed. 144 // The current composition text will be confirmed.
162 void MoveCursorToPreviousWord(bool select); 145 void MoveCursorLeftByWord(bool select);
163 146
164 // Moves the cursor right by one word (word boundry is defined by space). 147 // Moves the cursor right by one word (word boundry is defined by space).
165 // If |select| is true, it updates the selection accordingly. 148 // If |select| is true, it updates the selection accordingly.
166 // The current composition text will be confirmed. 149 // The current composition text will be confirmed.
167 void MoveCursorToNextWord(bool select); 150 void MoveCursorRightByWord(bool select);
168 151
169 // Moves the cursor to start of the textfield contents. 152 // Moves the cursor to start of the textfield contents.
170 // If |select| is true, it updates the selection accordingly. 153 // If |select| is true, it updates the selection accordingly.
171 // The current composition text will be confirmed. 154 // The current composition text will be confirmed.
172 void MoveCursorToHome(bool select); 155 void MoveCursorToLeftEnd(bool select);
173 156
174 // Moves the cursor to end of the textfield contents. 157 // Moves the cursor to end of the textfield contents.
175 // If |select| is true, it updates the selection accordingly. 158 // If |select| is true, it updates the selection accordingly.
176 // The current composition text will be confirmed. 159 // The current composition text will be confirmed.
177 void MoveCursorToEnd(bool select); 160 void MoveCursorToRightEnd(bool select);
178 161
179 // Moves the cursor to the specified |position|. 162 // Moves the cursor to the specified |position|.
180 // If |select| is true, it updates the selection accordingly. 163 // If |select| is true, it updates the selection accordingly.
181 // The current composition text will be confirmed. 164 // The current composition text will be confirmed.
182 bool MoveCursorTo(size_t position, bool select); 165 bool MoveCursorTo(size_t position, bool select);
183 166
184 // Returns the bounds of selected text. 167 // Returns the bounds of selected text.
185 gfx::Rect GetSelectionBounds(const gfx::Font& font) const; 168 std::vector<gfx::Rect> GetSelectionBounds() const;
186 169
187 // Selection related method 170 // Selection related method
188 171
189 // Returns the selected text. 172 // Returns the selected text.
190 string16 GetSelectedText() const; 173 string16 GetSelectedText() const;
191 174
192 void GetSelectedRange(ui::Range* range) const; 175 void GetSelectedRange(ui::Range* range) const;
193 176
194 // The current composition text will be confirmed. The 177 // The current composition text will be confirmed. The
195 // selection starts with the range's start position, 178 // selection starts with the range's start position,
(...skipping 20 matching lines...) Expand all
216 bool CanRedo(); 199 bool CanRedo();
217 200
218 // Undo edit. Returns true if undo changed the text. 201 // Undo edit. Returns true if undo changed the text.
219 bool Undo(); 202 bool Undo();
220 203
221 // Redo edit. Returns true if redo changed the text. 204 // Redo edit. Returns true if redo changed the text.
222 bool Redo(); 205 bool Redo();
223 206
224 // Returns visible text. If the field is password, it returns the 207 // Returns visible text. If the field is password, it returns the
225 // sequence of "*". 208 // sequence of "*".
226 string16 GetVisibleText() const { 209 string16 GetVisibleText() const;
227 return GetVisibleText(0U, text_.length());
228 }
229 210
230 // Cuts the currently selected text and puts it to clipboard. Returns true 211 // Cuts the currently selected text and puts it to clipboard. Returns true
231 // if text has changed after cutting. 212 // if text has changed after cutting.
232 bool Cut(); 213 bool Cut();
233 214
234 // Copies the currently selected text and puts it to clipboard. 215 // Copies the currently selected text and puts it to clipboard.
235 void Copy(); 216 void Copy();
236 217
237 // Pastes text from the clipboard at current cursor position. Returns true 218 // Pastes text from the clipboard at current cursor position. Returns true
238 // if text has changed after pasting. 219 // if text has changed after pasting.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 251
271 // Removes current composition text. 252 // Removes current composition text.
272 void CancelCompositionText(); 253 void CancelCompositionText();
273 254
274 // Retrieves the range of current composition text. 255 // Retrieves the range of current composition text.
275 void GetCompositionTextRange(ui::Range* range) const; 256 void GetCompositionTextRange(ui::Range* range) const;
276 257
277 // Returns true if there is composition text. 258 // Returns true if there is composition text.
278 bool HasCompositionText() const; 259 bool HasCompositionText() const;
279 260
280 TextStyle* CreateTextStyle();
281
282 void ClearAllTextStyles();
283
284 private: 261 private:
285 friend class NativeTextfieldViews; 262 friend class NativeTextfieldViews;
286 friend class NativeTextfieldViewsTest; 263 friend class NativeTextfieldViewsTest;
287 friend class TextfieldViewsModelTest; 264 friend class TextfieldViewsModelTest;
288 friend class TextStyle;
289 friend class UndoRedo_BasicTest; 265 friend class UndoRedo_BasicTest;
290 friend class UndoRedo_CutCopyPasteTest; 266 friend class UndoRedo_CutCopyPasteTest;
291 friend class UndoRedo_ReplaceTest; 267 friend class UndoRedo_ReplaceTest;
292 friend class internal::Edit; 268 friend class internal::Edit;
293 269
294 FRIEND_TEST_ALL_PREFIXES(TextfieldViewsModelTest, UndoRedo_BasicTest); 270 FRIEND_TEST_ALL_PREFIXES(TextfieldViewsModelTest, UndoRedo_BasicTest);
295 FRIEND_TEST_ALL_PREFIXES(TextfieldViewsModelTest, UndoRedo_CutCopyPasteTest); 271 FRIEND_TEST_ALL_PREFIXES(TextfieldViewsModelTest, UndoRedo_CutCopyPasteTest);
296 FRIEND_TEST_ALL_PREFIXES(TextfieldViewsModelTest, UndoRedo_ReplaceTest); 272 FRIEND_TEST_ALL_PREFIXES(TextfieldViewsModelTest, UndoRedo_ReplaceTest);
297 FRIEND_TEST_ALL_PREFIXES(TextfieldViewsModelTest, TextStyleTest);
298 273
299 // Returns the visible text given |start| and |end|. 274 // Returns the visible text given |start| and |end|.
300 string16 GetVisibleText(size_t start, size_t end) const; 275 string16 GetVisibleText(size_t start, size_t end) const;
301 276
302 // Utility for SelectWord(). Checks whether position pos is at word boundary.
303 bool IsPositionAtWordSelectionBoundary(size_t pos);
304
305 // Returns the normalized cursor position that does not exceed the
306 // text length.
307 size_t GetSafePosition(size_t position) const;
308
309 // Insert the given |text|. |mergeable| indicates if this insert 277 // Insert the given |text|. |mergeable| indicates if this insert
310 // operation can be merged to previous edit in the edit history. 278 // operation can be merged to previous edit in the edit history.
311 void InsertTextInternal(const string16& text, bool mergeable); 279 void InsertTextInternal(const string16& text, bool mergeable);
312 280
313 // Replace the current text with the given |text|. |mergeable| 281 // Replace the current text with the given |text|. |mergeable|
314 // indicates if this replace operation can be merged to previous 282 // indicates if this replace operation can be merged to previous
315 // edit in the edit history. 283 // edit in the edit history.
316 void ReplaceTextInternal(const string16& text, bool mergeable); 284 void ReplaceTextInternal(const string16& text, bool mergeable);
317 285
318 // Clears all edit history. 286 // Clears all edit history.
(...skipping 23 matching lines...) Expand all
342 // Note that the index is after deletion. 310 // Note that the index is after deletion.
343 // 3) Move the cursor to |new_cursor_pos|. 311 // 3) Move the cursor to |new_cursor_pos|.
344 void ModifyText(size_t delete_from, 312 void ModifyText(size_t delete_from,
345 size_t delete_to, 313 size_t delete_to,
346 const string16& new_text, 314 const string16& new_text,
347 size_t new_text_insert_at, 315 size_t new_text_insert_at,
348 size_t new_cursor_pos); 316 size_t new_cursor_pos);
349 317
350 void ClearComposition(); 318 void ClearComposition();
351 319
352 void ApplyTextStyle(const TextStyle* style, const ui::Range& range);
353
354 static TextStyle* CreateUnderlineStyle();
355
356 // Pointer to a TextfieldViewsModel::Delegate instance, should be provided by 320 // Pointer to a TextfieldViewsModel::Delegate instance, should be provided by
357 // the View object. 321 // the View object.
358 Delegate* delegate_; 322 Delegate* delegate_;
359 323
360 // The text in utf16 format. 324 // The stylized text, cursor, selection, and the visual layout model.
361 string16 text_; 325 gfx::RenderText* render_text_;
362
363 // Current cursor position.
364 size_t cursor_pos_;
365
366 // Selection range.
367 size_t selection_start_;
368
369 // Composition text range.
370 size_t composition_start_;
371 size_t composition_end_;
372 326
373 // True if the text is the password. 327 // True if the text is the password.
374 bool is_password_; 328 bool is_password_;
375 329
376 typedef std::list<internal::Edit*> EditHistory; 330 typedef std::list<internal::Edit*> EditHistory;
377 EditHistory edit_history_; 331 EditHistory edit_history_;
378 332
379 // An iterator that points to the current edit that can be undone. 333 // An iterator that points to the current edit that can be undone.
380 // This iterator moves from the |end()|, meaining no edit to undo, 334 // This iterator moves from the |end()|, meaining no edit to undo,
381 // to the last element (one before |end()|), meaning no edit to redo. 335 // to the last element (one before |end()|), meaning no edit to redo.
382 // There is no edit to undo (== end()) when: 336 // There is no edit to undo (== end()) when:
383 // 1) in initial state. (nothing to undo) 337 // 1) in initial state. (nothing to undo)
384 // 2) very 1st edit is undone. 338 // 2) very 1st edit is undone.
385 // 3) all edit history is removed. 339 // 3) all edit history is removed.
386 // There is no edit to redo (== last element or no element) when: 340 // There is no edit to redo (== last element or no element) when:
387 // 1) in initial state. (nothing to redo) 341 // 1) in initial state. (nothing to redo)
388 // 2) new edit is added. (redo history is cleared) 342 // 2) new edit is added. (redo history is cleared)
389 // 3) redone all undone edits. 343 // 3) redone all undone edits.
390 EditHistory::iterator current_edit_; 344 EditHistory::iterator current_edit_;
391 345
392 // This manages all styles objects.
393 TextStyles text_styles_;
394
395 // List of style ranges. Elements in the list never overlap each other.
396 // Elements are not sorted at the time of insertion, and gets sorted
397 // when it's painted (if necessary).
398 TextStyleRanges style_ranges_;
399 // True if the style_ranges_ needs to be sorted.
400 bool sort_style_ranges_;
401
402 // List of style ranges for composition text.
403 TextStyleRanges composition_style_ranges_;
404
405 DISALLOW_COPY_AND_ASSIGN(TextfieldViewsModel); 346 DISALLOW_COPY_AND_ASSIGN(TextfieldViewsModel);
406 }; 347 };
407 348
408 } // namespace views 349 } // namespace views
409 350
410 #endif // VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_VIEWS_MODEL_H_ 351 #endif // VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_VIEWS_MODEL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698