selection_model.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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.
  4. #ifndef UI_GFX_SELECTION_MODEL_H_
  5. #define UI_GFX_SELECTION_MODEL_H_
  6. #include <stddef.h>
  7. #include <vector>
  8. #include <iosfwd>
  9. #include <string>
  10. #include "ui/gfx/gfx_export.h"
  11. #include "ui/gfx/range/range.h"
  12. namespace gfx {
  13. // VisualCursorDirection and LogicalCursorDirection represent directions of
  14. // motion of the cursor in BiDi text. The combinations that make sense are:
  15. //
  16. // base::i18n::TextDirection VisualCursorDirection LogicalCursorDirection
  17. // LEFT_TO_RIGHT CURSOR_LEFT CURSOR_BACKWARD
  18. // LEFT_TO_RIGHT CURSOR_RIGHT CURSOR_FORWARD
  19. // RIGHT_TO_LEFT CURSOR_RIGHT CURSOR_BACKWARD
  20. // RIGHT_TO_LEFT CURSOR_LEFT CURSOR_FORWARD
  21. enum VisualCursorDirection {
  22. CURSOR_LEFT,
  23. CURSOR_RIGHT,
  24. CURSOR_UP,
  25. CURSOR_DOWN
  26. };
  27. enum LogicalCursorDirection {
  28. CURSOR_BACKWARD,
  29. CURSOR_FORWARD
  30. };
  31. // TODO(xji): publish bidi-editing guide line and replace the place holder.
  32. // SelectionModel is used to represent the logical selection and visual
  33. // position of cursor.
  34. //
  35. // For bi-directional text, the mapping between visual position and logical
  36. // position is not one-to-one. For example, logical text "abcDEF" where capital
  37. // letters stand for Hebrew, the visual display is "abcFED". According to the
  38. // bidi editing guide (http://bidi-editing-guideline):
  39. // 1. If pointing to the right half of the cell of a LTR character, the current
  40. // position must be set after this character and the caret must be displayed
  41. // after this character.
  42. // 2. If pointing to the right half of the cell of a RTL character, the current
  43. // position must be set before this character and the caret must be displayed
  44. // before this character.
  45. //
  46. // Pointing to the right half of 'c' and pointing to the right half of 'D' both
  47. // set the logical cursor position to 3. But the cursor displayed visually at
  48. // different places:
  49. // Pointing to the right half of 'c' displays the cursor right of 'c' as
  50. // "abc|FED".
  51. // Pointing to the right half of 'D' displays the cursor right of 'D' as
  52. // "abcFED|".
  53. // So, besides the logical selection start point and end point, we need extra
  54. // information to specify to which character the visual cursor is bound. This
  55. // is given by a "caret affinity" which is either CURSOR_BACKWARD (indicating
  56. // the trailing half of the 'c' in this case) or CURSOR_FORWARD (indicating
  57. // the leading half of the 'D').
  58. class GFX_EXPORT SelectionModel {
  59. public:
  60. // Create a default SelectionModel to be overwritten later.
  61. SelectionModel();
  62. // Create a SelectionModel representing a caret |position| without a
  63. // selection. The |affinity| is meaningful only when the caret is positioned
  64. // between bidi runs that are not visually contiguous: in that case, it
  65. // indicates the run to which the caret is attached for display purposes.
  66. SelectionModel(size_t position, LogicalCursorDirection affinity);
  67. // Create a SelectionModel representing a selection (which may be empty).
  68. // The caret position is the end of the range.
  69. SelectionModel(const Range& selection, LogicalCursorDirection affinity);
  70. // Create a SelectionModel representing multiple selections (which may be
  71. // empty but not overlapping). The end of the first range determines the caret
  72. // position.
  73. SelectionModel(const std::vector<Range>& selections,
  74. LogicalCursorDirection affinity);
  75. SelectionModel(const SelectionModel& selection_model);
  76. ~SelectionModel();
  77. // |selection| should overlap with neither |selection_| nor
  78. // |secondary_selections_|.
  79. void AddSecondarySelection(const Range& selection);
  80. const Range& selection() const { return selection_; }
  81. size_t caret_pos() const { return selection_.end(); }
  82. LogicalCursorDirection caret_affinity() const { return caret_affinity_; }
  83. const std::vector<Range>& secondary_selections() const {
  84. return secondary_selections_;
  85. }
  86. std::vector<Range> GetAllSelections() const;
  87. // WARNING: Generally the selection start should not be changed without
  88. // considering the effect on the caret affinity.
  89. void set_selection_start(uint32_t pos) { selection_.set_start(pos); }
  90. bool operator==(const SelectionModel& sel) const;
  91. bool operator!=(const SelectionModel& sel) const { return !(*this == sel); }
  92. std::string ToString() const;
  93. private:
  94. // Logical selection. The logical caret position is the end of the selection.
  95. Range selection_;
  96. // Secondary selections not associated with the cursor. Do not overlap.
  97. std::vector<Range> secondary_selections_;
  98. // The logical direction from the caret position (selection_.end()) to the
  99. // character it is attached to for display purposes. This matters only when
  100. // the surrounding characters are not visually contiguous, which happens only
  101. // in bidi text (and only at bidi run boundaries). The text is treated as
  102. // though it was surrounded on both sides by runs in the dominant text
  103. // direction. For example, supposing the dominant direction is LTR and the
  104. // logical text is "abcDEF", where DEF is right-to-left text, the visual
  105. // cursor will display as follows:
  106. // caret position CURSOR_BACKWARD affinity CURSOR_FORWARD affinity
  107. // 0 |abcFED |abcFED
  108. // 1 a|bcFED a|bcFED
  109. // 2 ab|cFED ab|cFED
  110. // 3 abc|FED abcFED|
  111. // 4 abcFE|D abcFE|D
  112. // 5 abcF|ED abcF|ED
  113. // 6 abc|FED abcFED|
  114. LogicalCursorDirection caret_affinity_;
  115. };
  116. GFX_EXPORT std::ostream& operator<<(std::ostream& out,
  117. const SelectionModel& model);
  118. } // namespace gfx
  119. #endif // UI_GFX_SELECTION_MODEL_H_