OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "views/controls/textfield/native_textfield_views.h" | 5 #include "views/controls/textfield/native_textfield_views.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 } | 193 } |
194 | 194 |
195 int NativeTextfieldViews::OnPerformDrop(const DropTargetEvent& event) { | 195 int NativeTextfieldViews::OnPerformDrop(const DropTargetEvent& event) { |
196 DCHECK(CanDrop(event.data())); | 196 DCHECK(CanDrop(event.data())); |
197 DCHECK(!initiating_drag_ || | 197 DCHECK(!initiating_drag_ || |
198 !GetRenderText()->IsPointInSelection(event.location())); | 198 !GetRenderText()->IsPointInSelection(event.location())); |
199 OnBeforeUserAction(); | 199 OnBeforeUserAction(); |
200 skip_input_method_cancel_composition_ = true; | 200 skip_input_method_cancel_composition_ = true; |
201 | 201 |
202 // TODO(msw): Remove final reference to FindCursorPosition. | 202 // TODO(msw): Remove final reference to FindCursorPosition. |
203 size_t drop_destination = | 203 gfx::SelectionModel drop_destination = |
204 GetRenderText()->FindCursorPosition(event.location()); | 204 GetRenderText()->FindCursorPosition(event.location()); |
205 string16 text; | 205 string16 text; |
206 event.data().GetString(&text); | 206 event.data().GetString(&text); |
207 | 207 |
208 // We'll delete the current selection for a drag and drop within this view. | 208 // We'll delete the current selection for a drag and drop within this view. |
209 bool move = initiating_drag_ && !event.IsControlDown() && | 209 bool move = initiating_drag_ && !event.IsControlDown() && |
210 event.source_operations() & ui::DragDropTypes::DRAG_MOVE; | 210 event.source_operations() & ui::DragDropTypes::DRAG_MOVE; |
211 if (move) { | 211 if (move) { |
212 ui::Range selected_range; | 212 ui::Range selected_range; |
213 model_->GetSelectedRange(&selected_range); | 213 model_->GetSelectedRange(&selected_range); |
214 // Adjust the drop destination if it is on or after the current selection. | 214 // Adjust the drop destination if it is on or after the current selection. |
215 if (selected_range.GetMax() <= drop_destination) | 215 if (selected_range.GetMax() <= drop_destination.selection_end()) |
216 drop_destination -= selected_range.length(); | 216 drop_destination.set_selection_end( |
217 else if (selected_range.GetMin() <= drop_destination) | 217 drop_destination.selection_end() - selected_range.length()); |
218 drop_destination = selected_range.GetMin(); | 218 else if (selected_range.GetMin() <= drop_destination.selection_end()) |
219 model_->DeleteSelectionAndInsertTextAt(text, drop_destination); | 219 drop_destination.set_selection_end(selected_range.GetMin()); |
| 220 model_->DeleteSelectionAndInsertTextAt(text, |
| 221 drop_destination.selection_end()); |
220 } else { | 222 } else { |
221 model_->MoveCursorTo(drop_destination, false); | 223 drop_destination.set_selection_start(drop_destination.selection_end()); |
| 224 model_->MoveCursorTo(drop_destination); |
222 // Drop always inserts text even if the textfield is not in insert mode. | 225 // Drop always inserts text even if the textfield is not in insert mode. |
223 model_->InsertText(text); | 226 model_->InsertText(text); |
224 } | 227 } |
225 skip_input_method_cancel_composition_ = false; | 228 skip_input_method_cancel_composition_ = false; |
226 UpdateAfterChange(true, true); | 229 UpdateAfterChange(true, true); |
227 OnAfterUserAction(); | 230 OnAfterUserAction(); |
228 return move ? ui::DragDropTypes::DRAG_MOVE : ui::DragDropTypes::DRAG_COPY; | 231 return move ? ui::DragDropTypes::DRAG_MOVE : ui::DragDropTypes::DRAG_COPY; |
229 } | 232 } |
230 | 233 |
231 void NativeTextfieldViews::OnDragDone() { | 234 void NativeTextfieldViews::OnDragDone() { |
(...skipping 12 matching lines...) Expand all Loading... |
244 void NativeTextfieldViews::OnFocus() { | 247 void NativeTextfieldViews::OnFocus() { |
245 NOTREACHED(); | 248 NOTREACHED(); |
246 } | 249 } |
247 | 250 |
248 void NativeTextfieldViews::OnBlur() { | 251 void NativeTextfieldViews::OnBlur() { |
249 NOTREACHED(); | 252 NOTREACHED(); |
250 } | 253 } |
251 | 254 |
252 void NativeTextfieldViews::SelectRect(const gfx::Point& start, | 255 void NativeTextfieldViews::SelectRect(const gfx::Point& start, |
253 const gfx::Point& end) { | 256 const gfx::Point& end) { |
254 size_t start_pos = GetRenderText()->FindCursorPosition(start); | 257 if (GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE) |
255 size_t end_pos = GetRenderText()->FindCursorPosition(end); | 258 return; |
256 SetSelectionRange(ui::Range(start_pos, end_pos)); | 259 |
| 260 gfx::SelectionModel start_pos = GetRenderText()->FindCursorPosition(start); |
| 261 gfx::SelectionModel end_pos = GetRenderText()->FindCursorPosition(end); |
| 262 |
| 263 OnBeforeUserAction(); |
| 264 // Merge selection models of "start_pos" and "end_pos" so that |
| 265 // selection start is the value from "start_pos", while selection end, |
| 266 // caret position, and caret placement are values from "end_pos". |
| 267 gfx::SelectionModel sel(end_pos); |
| 268 sel.set_selection_start(start_pos.selection_start()); |
| 269 model_->SelectSelectionModel(sel); |
| 270 |
| 271 OnCaretBoundsChanged(); |
| 272 SchedulePaint(); |
| 273 OnAfterUserAction(); |
257 } | 274 } |
258 | 275 |
259 gfx::NativeCursor NativeTextfieldViews::GetCursor(const MouseEvent& event) { | 276 gfx::NativeCursor NativeTextfieldViews::GetCursor(const MouseEvent& event) { |
260 bool in_selection = GetRenderText()->IsPointInSelection(event.location()); | 277 bool in_selection = GetRenderText()->IsPointInSelection(event.location()); |
261 bool drag_event = event.type() == ui::ET_MOUSE_DRAGGED; | 278 bool drag_event = event.type() == ui::ET_MOUSE_DRAGGED; |
262 bool text_cursor = !initiating_drag_ && (drag_event || !in_selection); | 279 bool text_cursor = !initiating_drag_ && (drag_event || !in_selection); |
263 #if defined(OS_WIN) | 280 #if defined(OS_WIN) |
264 static HCURSOR ibeam = LoadCursor(NULL, IDC_IBEAM); | 281 static HCURSOR ibeam = LoadCursor(NULL, IDC_IBEAM); |
265 static HCURSOR arrow = LoadCursor(NULL, IDC_ARROW); | 282 static HCURSOR arrow = LoadCursor(NULL, IDC_ARROW); |
266 return text_cursor ? ibeam : arrow; | 283 return text_cursor ? ibeam : arrow; |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
665 | 682 |
666 ui::TextInputType NativeTextfieldViews::GetTextInputType() { | 683 ui::TextInputType NativeTextfieldViews::GetTextInputType() { |
667 if (textfield_->read_only() || !textfield_->IsEnabled()) | 684 if (textfield_->read_only() || !textfield_->IsEnabled()) |
668 return ui::TEXT_INPUT_TYPE_NONE; | 685 return ui::TEXT_INPUT_TYPE_NONE; |
669 else if (textfield_->IsPassword()) | 686 else if (textfield_->IsPassword()) |
670 return ui::TEXT_INPUT_TYPE_PASSWORD; | 687 return ui::TEXT_INPUT_TYPE_PASSWORD; |
671 return ui::TEXT_INPUT_TYPE_TEXT; | 688 return ui::TEXT_INPUT_TYPE_TEXT; |
672 } | 689 } |
673 | 690 |
674 gfx::Rect NativeTextfieldViews::GetCaretBounds() { | 691 gfx::Rect NativeTextfieldViews::GetCaretBounds() { |
675 gfx::RenderText* render_text = GetRenderText(); | 692 return GetRenderText()->CursorBounds(); |
676 return render_text->GetCursorBounds(render_text->GetCursorPosition(), | |
677 render_text->insert_mode()); | |
678 } | 693 } |
679 | 694 |
680 bool NativeTextfieldViews::HasCompositionText() { | 695 bool NativeTextfieldViews::HasCompositionText() { |
681 return model_->HasCompositionText(); | 696 return model_->HasCompositionText(); |
682 } | 697 } |
683 | 698 |
684 bool NativeTextfieldViews::GetTextRange(ui::Range* range) { | 699 bool NativeTextfieldViews::GetTextRange(ui::Range* range) { |
685 // We don't allow the input method to retrieve or delete content from a | 700 // We don't allow the input method to retrieve or delete content from a |
686 // password box. | 701 // password box. |
687 if (GetTextInputType() != ui::TEXT_INPUT_TYPE_TEXT) | 702 if (GetTextInputType() != ui::TEXT_INPUT_TYPE_TEXT) |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
959 | 974 |
960 void NativeTextfieldViews::OnCaretBoundsChanged() { | 975 void NativeTextfieldViews::OnCaretBoundsChanged() { |
961 // TODO(suzhe): changed from DCHECK. See http://crbug.com/81320. | 976 // TODO(suzhe): changed from DCHECK. See http://crbug.com/81320. |
962 if (textfield_->GetInputMethod()) | 977 if (textfield_->GetInputMethod()) |
963 textfield_->GetInputMethod()->OnCaretBoundsChanged(textfield_); | 978 textfield_->GetInputMethod()->OnCaretBoundsChanged(textfield_); |
964 | 979 |
965 // Notify selection controller | 980 // Notify selection controller |
966 if (!touch_selection_controller_.get()) | 981 if (!touch_selection_controller_.get()) |
967 return; | 982 return; |
968 gfx::RenderText* render_text = GetRenderText(); | 983 gfx::RenderText* render_text = GetRenderText(); |
969 ui::Range range = render_text->GetSelection(); | 984 const gfx::SelectionModel& sel = render_text->selection_model(); |
970 gfx::Rect start_cursor = render_text->GetCursorBounds(range.start(), false); | 985 gfx::SelectionModel start_sel(sel.selection_start(), sel.selection_start(), |
971 gfx::Rect end_cursor = render_text->GetCursorBounds(range.end(), false); | 986 sel.selection_start(), gfx::SelectionModel::LEADING); |
| 987 gfx::Rect start_cursor = render_text->GetCursorBounds(start_sel, false); |
| 988 gfx::Rect end_cursor = render_text->GetCursorBounds(sel, false); |
972 gfx::Rect display_rect = render_text->display_rect(); | 989 gfx::Rect display_rect = render_text->display_rect(); |
973 int total_offset_x = display_rect.x() + render_text->display_offset().x(); | 990 int total_offset_x = display_rect.x() + render_text->display_offset().x(); |
974 int total_offset_y = display_rect.y() + render_text->display_offset().y() + | 991 int total_offset_y = display_rect.y() + render_text->display_offset().y() + |
975 (display_rect.height() - start_cursor.height()) / 2; | 992 (display_rect.height() - start_cursor.height()) / 2; |
976 gfx::Point start(start_cursor.x() + total_offset_x, | 993 gfx::Point start(start_cursor.x() + total_offset_x, |
977 start_cursor.bottom() + total_offset_y); | 994 start_cursor.bottom() + total_offset_y); |
978 gfx::Point end(end_cursor.x() + total_offset_x, | 995 gfx::Point end(end_cursor.x() + total_offset_x, |
979 end_cursor.bottom() + total_offset_y); | 996 end_cursor.bottom() + total_offset_y); |
980 touch_selection_controller_->SelectionChanged(start, end); | 997 touch_selection_controller_->SelectionChanged(start, end); |
981 } | 998 } |
(...skipping 28 matching lines...) Expand all Loading... |
1010 // Filter out all control characters, including tab and new line characters, | 1027 // Filter out all control characters, including tab and new line characters, |
1011 // and all characters with Alt modifier. But we need to allow characters with | 1028 // and all characters with Alt modifier. But we need to allow characters with |
1012 // AltGr modifier. | 1029 // AltGr modifier. |
1013 // On Windows AltGr is represented by Alt+Ctrl, and on Linux it's a different | 1030 // On Windows AltGr is represented by Alt+Ctrl, and on Linux it's a different |
1014 // flag that we don't care about. | 1031 // flag that we don't care about. |
1015 return ((ch >= 0x20 && ch < 0x7F) || ch > 0x9F) && | 1032 return ((ch >= 0x20 && ch < 0x7F) || ch > 0x9F) && |
1016 (flags & ~(ui::EF_SHIFT_DOWN | ui::EF_CAPS_LOCK_DOWN)) != ui::EF_ALT_DOWN; | 1033 (flags & ~(ui::EF_SHIFT_DOWN | ui::EF_CAPS_LOCK_DOWN)) != ui::EF_ALT_DOWN; |
1017 } | 1034 } |
1018 | 1035 |
1019 } // namespace views | 1036 } // namespace views |
OLD | NEW |