diff options
Diffstat (limited to 'chromium/ui/gfx/selection_model.h')
-rw-r--r-- | chromium/ui/gfx/selection_model.h | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/chromium/ui/gfx/selection_model.h b/chromium/ui/gfx/selection_model.h new file mode 100644 index 00000000000..b99b383714b --- /dev/null +++ b/chromium/ui/gfx/selection_model.h @@ -0,0 +1,113 @@ +// 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_GFX_SELECTION_MODEL_H_ +#define UI_GFX_SELECTION_MODEL_H_ + +#include <string> + +#include "ui/base/range/range.h" +#include "ui/base/ui_export.h" + +namespace gfx { + +// VisualCursorDirection and LogicalCursorDirection represent directions of +// motion of the cursor in BiDi text. The combinations that make sense are: +// +// base::i18n::TextDirection VisualCursorDirection LogicalCursorDirection +// LEFT_TO_RIGHT CURSOR_LEFT CURSOR_BACKWARD +// LEFT_TO_RIGHT CURSOR_RIGHT CURSOR_FORWARD +// RIGHT_TO_LEFT CURSOR_RIGHT CURSOR_BACKWARD +// RIGHT_TO_LEFT CURSOR_LEFT CURSOR_FORWARD +enum VisualCursorDirection { + CURSOR_LEFT, + CURSOR_RIGHT +}; +enum LogicalCursorDirection { + CURSOR_BACKWARD, + CURSOR_FORWARD +}; + +// TODO(xji): publish bidi-editing guide line and replace the place holder. +// SelectionModel is used to represent the logical selection and visual +// position of cursor. +// +// For bi-directional text, the mapping between visual position and logical +// position is not one-to-one. For example, logical text "abcDEF" where capital +// letters stand for Hebrew, the visual display is "abcFED". According to the +// bidi editing guide (http://bidi-editing-guideline): +// 1. If pointing to the right half of the cell of a LTR character, the current +// position must be set after this character and the caret must be displayed +// after this character. +// 2. If pointing to the right half of the cell of a RTL character, the current +// position must be set before this character and the caret must be displayed +// before this character. +// +// Pointing to the right half of 'c' and pointing to the right half of 'D' both +// set the logical cursor position to 3. But the cursor displayed visually at +// different places: +// Pointing to the right half of 'c' displays the cursor right of 'c' as +// "abc|FED". +// Pointing to the right half of 'D' displays the cursor right of 'D' as +// "abcFED|". +// So, besides the logical selection start point and end point, we need extra +// information to specify to which character the visual cursor is bound. This +// is given by a "caret affinity" which is either CURSOR_BACKWARD (indicating +// the trailing half of the 'c' in this case) or CURSOR_FORWARD (indicating +// the leading half of the 'D'). +class UI_EXPORT SelectionModel { + public: + // Create a default SelectionModel to be overwritten later. + SelectionModel(); + // Create a SelectionModel representing a caret |position| without a + // selection. The |affinity| is meaningful only when the caret is positioned + // between bidi runs that are not visually contiguous: in that case, it + // indicates the run to which the caret is attached for display purposes. + SelectionModel(size_t position, LogicalCursorDirection affinity); + // Create a SelectionModel representing a selection (which may be empty). + // The caret position is the end of the range. + SelectionModel(ui::Range selection, LogicalCursorDirection affinity); + + const ui::Range& selection() const { return selection_; } + size_t caret_pos() const { return selection_.end(); } + LogicalCursorDirection caret_affinity() const { return caret_affinity_; } + + bool operator==(const SelectionModel& sel) const; + bool operator!=(const SelectionModel& sel) const { return !(*this == sel); } + + std::string ToString() const; + + private: + friend class RenderText; + + // TODO(benrg): Generally the selection start should not be changed without + // considering the effect on the caret affinity. This setter is exposed only + // to RenderText to discourage misuse, and should probably be removed. + void set_selection_start(size_t pos) { selection_.set_start(pos); } + + // Logical selection. The logical caret position is the end of the selection. + ui::Range selection_; + + // The logical direction from the caret position (selection_.end()) to the + // character it is attached to for display purposes. This matters only when + // the surrounding characters are not visually contiguous, which happens only + // in bidi text (and only at bidi run boundaries). The text is treated as + // though it was surrounded on both sides by runs in the dominant text + // direction. For example, supposing the dominant direction is LTR and the + // logical text is "abcDEF", where DEF is right-to-left text, the visual + // cursor will display as follows: + // caret position CURSOR_BACKWARD affinity CURSOR_FORWARD affinity + // 0 |abcFED |abcFED + // 1 a|bcFED a|bcFED + // 2 ab|cFED ab|cFED + // 3 abc|FED abcFED| + // 4 abcFE|D abcFE|D + // 5 abcF|ED abcF|ED + // 6 abc|FED abcFED| + LogicalCursorDirection caret_affinity_; +}; + +} // namespace gfx + +#endif // UI_GFX_SELECTION_MODEL_H_ |