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

Side by Side Diff: ui/views/cocoa/bridged_content_view.mm

Issue 2955073002: Manky attempt with TextInputClient
Patch Set: Created 3 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
« no previous file with comments | « ui/views/accessibility/native_view_accessibility_base.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 #import "ui/views/cocoa/bridged_content_view.h" 5 #import "ui/views/cocoa/bridged_content_view.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #import "base/mac/mac_util.h" 8 #import "base/mac/mac_util.h"
9 #import "base/mac/scoped_nsobject.h" 9 #import "base/mac/scoped_nsobject.h"
10 #import "base/mac/sdk_forward_declarations.h" 10 #import "base/mac/sdk_forward_declarations.h"
11 #include "base/strings/sys_string_conversions.h" 11 #include "base/strings/sys_string_conversions.h"
12 #include "skia/ext/skia_utils_mac.h" 12 #include "skia/ext/skia_utils_mac.h"
13 #import "ui/base/cocoa/appkit_utils.h" 13 #import "ui/base/cocoa/appkit_utils.h"
14 #include "ui/base/cocoa/cocoa_base_utils.h" 14 #include "ui/base/cocoa/cocoa_base_utils.h"
15 #include "ui/base/dragdrop/drag_drop_types.h" 15 #include "ui/base/dragdrop/drag_drop_types.h"
16 #include "ui/base/dragdrop/os_exchange_data_provider_mac.h" 16 #include "ui/base/dragdrop/os_exchange_data_provider_mac.h"
17 #include "ui/base/ime/input_method.h" 17 #include "ui/base/ime/input_method.h"
18 #include "ui/base/ime/text_edit_commands.h" 18 #include "ui/base/ime/text_edit_commands.h"
19 #include "ui/base/ime/text_input_client.h" 19 #include "ui/base/ime/text_input_client.h"
20 #include "ui/base/text/text_properties.h"
20 #include "ui/compositor/canvas_painter.h" 21 #include "ui/compositor/canvas_painter.h"
21 #import "ui/events/cocoa/cocoa_event_utils.h" 22 #import "ui/events/cocoa/cocoa_event_utils.h"
22 #include "ui/events/event_utils.h" 23 #include "ui/events/event_utils.h"
23 #include "ui/events/keycodes/dom/dom_code.h" 24 #include "ui/events/keycodes/dom/dom_code.h"
24 #import "ui/events/keycodes/keyboard_code_conversion_mac.h" 25 #import "ui/events/keycodes/keyboard_code_conversion_mac.h"
25 #include "ui/gfx/canvas_paint_mac.h" 26 #include "ui/gfx/canvas_paint_mac.h"
26 #include "ui/gfx/decorated_text.h" 27 #include "ui/gfx/decorated_text.h"
27 #include "ui/gfx/geometry/rect.h" 28 #include "ui/gfx/geometry/rect.h"
28 #import "ui/gfx/mac/coordinate_conversion.h" 29 #import "ui/gfx/mac/coordinate_conversion.h"
29 #include "ui/gfx/path.h" 30 #include "ui/gfx/path.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 } 78 }
78 79
79 // Dispatch |event| to |menu_controller| and return true if |event| is 80 // Dispatch |event| to |menu_controller| and return true if |event| is
80 // swallowed. 81 // swallowed.
81 bool DispatchEventToMenu(MenuController* menu_controller, ui::KeyEvent* event) { 82 bool DispatchEventToMenu(MenuController* menu_controller, ui::KeyEvent* event) {
82 return menu_controller && 83 return menu_controller &&
83 menu_controller->OnWillDispatchKeyEvent(event) == 84 menu_controller->OnWillDispatchKeyEvent(event) ==
84 ui::POST_DISPATCH_NONE; 85 ui::POST_DISPATCH_NONE;
85 } 86 }
86 87
87 // Returns true if |client| has RTL text.
88 bool IsTextRTL(const ui::TextInputClient* client) {
89 return client && client->GetTextDirection() == base::i18n::RIGHT_TO_LEFT;
90 }
91
92 // Returns the boundary rectangle for composition characters in the
93 // |requested_range|. Sets |actual_range| corresponding to the returned
94 // rectangle. For cases, where there is no composition text or the
95 // |requested_range| lies outside the composition range, a zero width rectangle
96 // corresponding to the caret bounds is returned. Logic used is similar to
97 // RenderWidgetHostViewMac::GetCachedFirstRectForCharacterRange(...).
98 gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
99 const gfx::Range& requested_range,
100 gfx::Range* actual_range) {
101 // NSRange doesn't support reversed ranges.
102 DCHECK(!requested_range.is_reversed());
103 DCHECK(actual_range);
104
105 // Set up default return values, to be returned in case of unusual cases.
106 gfx::Rect default_rect;
107 *actual_range = gfx::Range::InvalidRange();
108 if (!client)
109 return default_rect;
110
111 default_rect = client->GetCaretBounds();
112 default_rect.set_width(0);
113
114 // If possible, modify actual_range to correspond to caret position.
115 gfx::Range selection_range;
116 if (client->GetSelectionRange(&selection_range)) {
117 // Caret bounds correspond to end index of selection_range.
118 *actual_range = gfx::Range(selection_range.end());
119 }
120
121 gfx::Range composition_range;
122 if (!client->HasCompositionText() ||
123 !client->GetCompositionTextRange(&composition_range) ||
124 !composition_range.Contains(requested_range))
125 return default_rect;
126
127 DCHECK(!composition_range.is_reversed());
128
129 const size_t from = requested_range.start() - composition_range.start();
130 const size_t to = requested_range.end() - composition_range.start();
131
132 // Pick the first character's bounds as the initial rectangle, then grow it to
133 // the full |requested_range| if possible.
134 const bool request_is_composition_end = from == composition_range.length();
135 const size_t first_index = request_is_composition_end ? from - 1 : from;
136 gfx::Rect union_rect;
137 if (!client->GetCompositionCharacterBounds(first_index, &union_rect))
138 return default_rect;
139
140 // If requested_range is empty, return a zero width rectangle corresponding to
141 // it.
142 if (from == to) {
143 if (request_is_composition_end && !IsTextRTL(client)) {
144 // In case of an empty requested range at end of composition, return the
145 // rectangle to the right of the last compositioned character.
146 union_rect.set_origin(union_rect.top_right());
147 }
148 union_rect.set_width(0);
149 *actual_range = requested_range;
150 return union_rect;
151 }
152
153 // Toolkit-views textfields are always single-line, so no need to check for
154 // line breaks.
155 for (size_t i = from + 1; i < to; i++) {
156 gfx::Rect current_rect;
157 if (client->GetCompositionCharacterBounds(i, &current_rect)) {
158 union_rect.Union(current_rect);
159 } else {
160 *actual_range =
161 gfx::Range(requested_range.start(), i + composition_range.start());
162 return union_rect;
163 }
164 }
165 *actual_range = requested_range;
166 return union_rect;
167 }
168
169 // Returns the string corresponding to |requested_range| for the given |client|. 88 // Returns the string corresponding to |requested_range| for the given |client|.
170 // If a gfx::Range::InvalidRange() is passed, the full string stored by |client| 89 // If a gfx::Range::InvalidRange() is passed, the full string stored by |client|
171 // is returned. Sets |actual_range| corresponding to the returned string. 90 // is returned. Sets |actual_range| corresponding to the returned string.
172 base::string16 AttributedSubstringForRangeHelper( 91 base::string16 AttributedSubstringForRangeHelper(
173 const ui::TextInputClient* client, 92 const ui::TextInputClient* client,
174 const gfx::Range& requested_range, 93 const gfx::Range& requested_range,
175 gfx::Range* actual_range) { 94 gfx::Range* actual_range) {
176 // NSRange doesn't support reversed ranges. 95 // NSRange doesn't support reversed ranges.
177 DCHECK(!requested_range.is_reversed()); 96 DCHECK(!requested_range.is_reversed());
178 DCHECK(actual_range); 97 DCHECK(actual_range);
(...skipping 1008 matching lines...) Expand 10 before | Expand all | Expand 10 after
1187 } 1106 }
1188 1107
1189 - (void)moveWordLeftAndModifySelection:(id)sender { 1108 - (void)moveWordLeftAndModifySelection:(id)sender {
1190 [self handleAction:ui::TextEditCommand::MOVE_WORD_LEFT_AND_MODIFY_SELECTION 1109 [self handleAction:ui::TextEditCommand::MOVE_WORD_LEFT_AND_MODIFY_SELECTION
1191 keyCode:ui::VKEY_LEFT 1110 keyCode:ui::VKEY_LEFT
1192 domCode:ui::DomCode::ARROW_LEFT 1111 domCode:ui::DomCode::ARROW_LEFT
1193 eventFlags:ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN]; 1112 eventFlags:ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN];
1194 } 1113 }
1195 1114
1196 - (void)moveToLeftEndOfLine:(id)sender { 1115 - (void)moveToLeftEndOfLine:(id)sender {
1197 IsTextRTL(textInputClient_) ? [self moveToEndOfLine:sender] 1116 ui::IsTextRTL(textInputClient_) ? [self moveToEndOfLine:sender]
1198 : [self moveToBeginningOfLine:sender]; 1117 : [self moveToBeginningOfLine:sender];
1199 } 1118 }
1200 1119
1201 - (void)moveToRightEndOfLine:(id)sender { 1120 - (void)moveToRightEndOfLine:(id)sender {
1202 IsTextRTL(textInputClient_) ? [self moveToBeginningOfLine:sender] 1121 ui::IsTextRTL(textInputClient_) ? [self moveToBeginningOfLine:sender]
1203 : [self moveToEndOfLine:sender]; 1122 : [self moveToEndOfLine:sender];
1204 } 1123 }
1205 1124
1206 - (void)moveToLeftEndOfLineAndModifySelection:(id)sender { 1125 - (void)moveToLeftEndOfLineAndModifySelection:(id)sender {
1207 IsTextRTL(textInputClient_) 1126 ui::IsTextRTL(textInputClient_)
1208 ? [self moveToEndOfLineAndModifySelection:sender] 1127 ? [self moveToEndOfLineAndModifySelection:sender]
1209 : [self moveToBeginningOfLineAndModifySelection:sender]; 1128 : [self moveToBeginningOfLineAndModifySelection:sender];
1210 } 1129 }
1211 1130
1212 - (void)moveToRightEndOfLineAndModifySelection:(id)sender { 1131 - (void)moveToRightEndOfLineAndModifySelection:(id)sender {
1213 IsTextRTL(textInputClient_) 1132 ui::IsTextRTL(textInputClient_)
1214 ? [self moveToBeginningOfLineAndModifySelection:sender] 1133 ? [self moveToBeginningOfLineAndModifySelection:sender]
1215 : [self moveToEndOfLineAndModifySelection:sender]; 1134 : [self moveToEndOfLineAndModifySelection:sender];
1216 } 1135 }
1217 1136
1218 // Graphical Element transposition 1137 // Graphical Element transposition
1219 1138
1220 - (void)transpose:(id)sender { 1139 - (void)transpose:(id)sender {
1221 [self handleAction:ui::TextEditCommand::TRANSPOSE 1140 [self handleAction:ui::TextEditCommand::TRANSPOSE
1222 keyCode:ui::VKEY_T 1141 keyCode:ui::VKEY_T
1223 domCode:ui::DomCode::US_T 1142 domCode:ui::DomCode::US_T
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1378 // For events that AppKit sends via doCommandBySelector:, first attempt to 1297 // For events that AppKit sends via doCommandBySelector:, first attempt to
1379 // handle as a Widget accelerator. Forward along the responder chain only if 1298 // handle as a Widget accelerator. Forward along the responder chain only if
1380 // the Widget doesn't handle it. 1299 // the Widget doesn't handle it.
1381 if (![self handleUnhandledKeyDownAsKeyEvent]) 1300 if (![self handleUnhandledKeyDownAsKeyEvent])
1382 [[self nextResponder] doCommandBySelector:selector]; 1301 [[self nextResponder] doCommandBySelector:selector];
1383 } 1302 }
1384 1303
1385 - (NSRect)firstRectForCharacterRange:(NSRange)range 1304 - (NSRect)firstRectForCharacterRange:(NSRange)range
1386 actualRange:(NSRangePointer)actualNSRange { 1305 actualRange:(NSRangePointer)actualNSRange {
1387 gfx::Range actualRange; 1306 gfx::Range actualRange;
1388 gfx::Rect rect = GetFirstRectForRangeHelper(textInputClient_, 1307 gfx::Rect rect = ui::GetFirstRectForTextInputRange(
1389 gfx::Range(range), &actualRange); 1308 textInputClient_, gfx::Range(range), &actualRange);
1390 if (actualNSRange) 1309 if (actualNSRange)
1391 *actualNSRange = actualRange.ToNSRange(); 1310 *actualNSRange = actualRange.ToNSRange();
1392 return gfx::ScreenRectToNSRect(rect); 1311 return gfx::ScreenRectToNSRect(rect);
1393 } 1312 }
1394 1313
1395 - (BOOL)hasMarkedText { 1314 - (BOOL)hasMarkedText {
1396 return textInputClient_ && textInputClient_->HasCompositionText(); 1315 return textInputClient_ && textInputClient_->HasCompositionText();
1397 } 1316 }
1398 1317
1399 - (void)insertText:(id)text replacementRange:(NSRange)replacementRange { 1318 - (void)insertText:(id)text replacementRange:(NSRange)replacementRange {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1518 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point]; 1437 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point];
1519 } 1438 }
1520 1439
1521 - (id)accessibilityFocusedUIElement { 1440 - (id)accessibilityFocusedUIElement {
1522 if (!hostedView_) 1441 if (!hostedView_)
1523 return nil; 1442 return nil;
1524 return [hostedView_->GetNativeViewAccessible() accessibilityFocusedUIElement]; 1443 return [hostedView_->GetNativeViewAccessible() accessibilityFocusedUIElement];
1525 } 1444 }
1526 1445
1527 @end 1446 @end
OLDNEW
« no previous file with comments | « ui/views/accessibility/native_view_accessibility_base.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698