15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef UI_GFX_SELECTION_MODEL_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UI_GFX_SELECTION_MODEL_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/gfx/gfx_export.h" 1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/gfx/range/range.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// VisualCursorDirection and LogicalCursorDirection represent directions of 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// motion of the cursor in BiDi text. The combinations that make sense are: 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// base::i18n::TextDirection VisualCursorDirection LogicalCursorDirection 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LEFT_TO_RIGHT CURSOR_LEFT CURSOR_BACKWARD 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LEFT_TO_RIGHT CURSOR_RIGHT CURSOR_FORWARD 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RIGHT_TO_LEFT CURSOR_RIGHT CURSOR_BACKWARD 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RIGHT_TO_LEFT CURSOR_LEFT CURSOR_FORWARD 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum VisualCursorDirection { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CURSOR_LEFT, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CURSOR_RIGHT 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum LogicalCursorDirection { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CURSOR_BACKWARD, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CURSOR_FORWARD 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(xji): publish bidi-editing guide line and replace the place holder. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SelectionModel is used to represent the logical selection and visual 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// position of cursor. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For bi-directional text, the mapping between visual position and logical 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// position is not one-to-one. For example, logical text "abcDEF" where capital 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// letters stand for Hebrew, the visual display is "abcFED". According to the 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bidi editing guide (http://bidi-editing-guideline): 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1. If pointing to the right half of the cell of a LTR character, the current 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// position must be set after this character and the caret must be displayed 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// after this character. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2. If pointing to the right half of the cell of a RTL character, the current 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// position must be set before this character and the caret must be displayed 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// before this character. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Pointing to the right half of 'c' and pointing to the right half of 'D' both 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// set the logical cursor position to 3. But the cursor displayed visually at 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// different places: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Pointing to the right half of 'c' displays the cursor right of 'c' as 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "abc|FED". 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Pointing to the right half of 'D' displays the cursor right of 'D' as 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "abcFED|". 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// So, besides the logical selection start point and end point, we need extra 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// information to specify to which character the visual cursor is bound. This 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is given by a "caret affinity" which is either CURSOR_BACKWARD (indicating 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the trailing half of the 'c' in this case) or CURSOR_FORWARD (indicating 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the leading half of the 'D'). 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class GFX_EXPORT SelectionModel { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a default SelectionModel to be overwritten later. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a SelectionModel representing a caret |position| without a 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // selection. The |affinity| is meaningful only when the caret is positioned 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // between bidi runs that are not visually contiguous: in that case, it 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // indicates the run to which the caret is attached for display purposes. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel(size_t position, LogicalCursorDirection affinity); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a SelectionModel representing a selection (which may be empty). 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The caret position is the end of the range. 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SelectionModel(const Range& selection, LogicalCursorDirection affinity); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const Range& selection() const { return selection_; } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t caret_pos() const { return selection_.end(); } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogicalCursorDirection caret_affinity() const { return caret_affinity_; } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // WARNING: Generally the selection start should not be changed without 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // considering the effect on the caret affinity. 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void set_selection_start(size_t pos) { selection_.set_start(pos); } 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator==(const SelectionModel& sel) const; 8158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch bool operator!=(const SelectionModel& sel) const { return !(*this == sel); } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string ToString() const; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Logical selection. The logical caret position is the end of the selection. 87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Range selection_; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The logical direction from the caret position (selection_.end()) to the 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // character it is attached to for display purposes. This matters only when 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the surrounding characters are not visually contiguous, which happens only 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in bidi text (and only at bidi run boundaries). The text is treated as 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // though it was surrounded on both sides by runs in the dominant text 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // direction. For example, supposing the dominant direction is LTR and the 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // logical text is "abcDEF", where DEF is right-to-left text, the visual 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cursor will display as follows: 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // caret position CURSOR_BACKWARD affinity CURSOR_FORWARD affinity 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 0 |abcFED |abcFED 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1 a|bcFED a|bcFED 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2 ab|cFED ab|cFED 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3 abc|FED abcFED| 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 4 abcFE|D abcFE|D 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 5 abcF|ED abcF|ED 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 6 abc|FED abcFED| 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogicalCursorDirection caret_affinity_; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gfx 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // UI_GFX_SELECTION_MODEL_H_ 111