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_GFX_SELECTION_MODEL_H_
6 #define UI_GFX_SELECTION_MODEL_H_
10 #include "ui/gfx/gfx_export.h"
11 #include "ui/gfx/range/range.h"
15 // VisualCursorDirection and LogicalCursorDirection represent directions of
16 // motion of the cursor in BiDi text. The combinations that make sense are:
18 // base::i18n::TextDirection VisualCursorDirection LogicalCursorDirection
19 // LEFT_TO_RIGHT CURSOR_LEFT CURSOR_BACKWARD
20 // LEFT_TO_RIGHT CURSOR_RIGHT CURSOR_FORWARD
21 // RIGHT_TO_LEFT CURSOR_RIGHT CURSOR_BACKWARD
22 // RIGHT_TO_LEFT CURSOR_LEFT CURSOR_FORWARD
23 enum VisualCursorDirection
{
27 enum LogicalCursorDirection
{
32 // TODO(xji): publish bidi-editing guide line and replace the place holder.
33 // SelectionModel is used to represent the logical selection and visual
34 // position of cursor.
36 // For bi-directional text, the mapping between visual position and logical
37 // position is not one-to-one. For example, logical text "abcDEF" where capital
38 // letters stand for Hebrew, the visual display is "abcFED". According to the
39 // bidi editing guide (http://bidi-editing-guideline):
40 // 1. If pointing to the right half of the cell of a LTR character, the current
41 // position must be set after this character and the caret must be displayed
42 // after this character.
43 // 2. If pointing to the right half of the cell of a RTL character, the current
44 // position must be set before this character and the caret must be displayed
45 // before this character.
47 // Pointing to the right half of 'c' and pointing to the right half of 'D' both
48 // set the logical cursor position to 3. But the cursor displayed visually at
50 // Pointing to the right half of 'c' displays the cursor right of 'c' as
52 // Pointing to the right half of 'D' displays the cursor right of 'D' as
54 // So, besides the logical selection start point and end point, we need extra
55 // information to specify to which character the visual cursor is bound. This
56 // is given by a "caret affinity" which is either CURSOR_BACKWARD (indicating
57 // the trailing half of the 'c' in this case) or CURSOR_FORWARD (indicating
58 // the leading half of the 'D').
59 class GFX_EXPORT SelectionModel
{
61 // Create a default SelectionModel to be overwritten later.
63 // Create a SelectionModel representing a caret |position| without a
64 // selection. The |affinity| is meaningful only when the caret is positioned
65 // between bidi runs that are not visually contiguous: in that case, it
66 // indicates the run to which the caret is attached for display purposes.
67 SelectionModel(size_t position
, LogicalCursorDirection affinity
);
68 // Create a SelectionModel representing a selection (which may be empty).
69 // The caret position is the end of the range.
70 SelectionModel(const Range
& selection
, LogicalCursorDirection affinity
);
72 const Range
& selection() const { return selection_
; }
73 size_t caret_pos() const { return selection_
.end(); }
74 LogicalCursorDirection
caret_affinity() const { return caret_affinity_
; }
76 // WARNING: Generally the selection start should not be changed without
77 // considering the effect on the caret affinity.
78 void set_selection_start(size_t pos
) { selection_
.set_start(pos
); }
80 bool operator==(const SelectionModel
& sel
) const;
81 bool operator!=(const SelectionModel
& sel
) const { return !(*this == sel
); }
83 std::string
ToString() const;
86 // Logical selection. The logical caret position is the end of the selection.
89 // The logical direction from the caret position (selection_.end()) to the
90 // character it is attached to for display purposes. This matters only when
91 // the surrounding characters are not visually contiguous, which happens only
92 // in bidi text (and only at bidi run boundaries). The text is treated as
93 // though it was surrounded on both sides by runs in the dominant text
94 // direction. For example, supposing the dominant direction is LTR and the
95 // logical text is "abcDEF", where DEF is right-to-left text, the visual
96 // cursor will display as follows:
97 // caret position CURSOR_BACKWARD affinity CURSOR_FORWARD affinity
105 LogicalCursorDirection caret_affinity_
;
110 #endif // UI_GFX_SELECTION_MODEL_H_