Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "ui/views/controls/textfield/textfield.h" | 5 #include "ui/views/controls/textfield/textfield.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "grit/ui_strings.h" | 10 #include "grit/ui_strings.h" |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 305 return; | 305 return; |
| 306 model_->InsertText(new_text); | 306 model_->InsertText(new_text); |
| 307 OnCaretBoundsChanged(); | 307 OnCaretBoundsChanged(); |
| 308 SchedulePaint(); | 308 SchedulePaint(); |
| 309 } | 309 } |
| 310 | 310 |
| 311 base::i18n::TextDirection Textfield::GetTextDirection() const { | 311 base::i18n::TextDirection Textfield::GetTextDirection() const { |
| 312 return GetRenderText()->GetTextDirection(); | 312 return GetRenderText()->GetTextDirection(); |
| 313 } | 313 } |
| 314 | 314 |
| 315 base::string16 Textfield::GetSelectedText() const { | |
| 316 return model_->GetSelectedText(); | |
| 317 } | |
| 318 | |
| 315 void Textfield::SelectAll(bool reversed) { | 319 void Textfield::SelectAll(bool reversed) { |
| 316 model_->SelectAll(reversed); | 320 model_->SelectAll(reversed); |
| 317 UpdateSelectionClipboard(); | 321 UpdateSelectionClipboard(); |
| 318 UpdateAfterChange(false, true); | 322 UpdateAfterChange(false, true); |
| 319 } | 323 } |
| 320 | 324 |
| 321 base::string16 Textfield::GetSelectedText() const { | |
| 322 return model_->GetSelectedText(); | |
| 323 } | |
| 324 | |
| 325 void Textfield::ClearSelection() { | 325 void Textfield::ClearSelection() { |
| 326 model_->ClearSelection(); | 326 model_->ClearSelection(); |
| 327 UpdateAfterChange(false, true); | 327 UpdateAfterChange(false, true); |
| 328 } | 328 } |
| 329 | 329 |
| 330 bool Textfield::HasSelection() const { | 330 bool Textfield::HasSelection() const { |
| 331 return !GetSelectedRange().is_empty(); | 331 return !GetSelectedRange().is_empty(); |
| 332 } | 332 } |
| 333 | 333 |
| 334 SkColor Textfield::GetTextColor() const { | 334 SkColor Textfield::GetTextColor() const { |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 545 PasteSelectionClipboard(event); | 545 PasteSelectionClipboard(event); |
| 546 } | 546 } |
| 547 } | 547 } |
| 548 #endif | 548 #endif |
| 549 } | 549 } |
| 550 | 550 |
| 551 return true; | 551 return true; |
| 552 } | 552 } |
| 553 | 553 |
| 554 bool Textfield::OnMouseDragged(const ui::MouseEvent& event) { | 554 bool Textfield::OnMouseDragged(const ui::MouseEvent& event) { |
| 555 last_drag_location_ = event.location(); | |
| 556 | |
| 555 // Don't adjust the cursor on a potential drag and drop, or if the mouse | 557 // Don't adjust the cursor on a potential drag and drop, or if the mouse |
| 556 // movement from the last mouse click does not exceed the drag threshold. | 558 // movement from the last mouse click does not exceed the drag threshold. |
| 557 if (initiating_drag_ || !event.IsOnlyLeftMouseButton() || | 559 if (initiating_drag_ || !event.IsOnlyLeftMouseButton() || |
| 558 !ExceededDragThreshold(event.location() - last_click_location_)) { | 560 !ExceededDragThreshold(last_drag_location_ - last_click_location_)) { |
| 559 return true; | 561 return true; |
| 560 } | 562 } |
| 561 | 563 |
| 562 OnBeforeUserAction(); | 564 // A timer is used to continuously scroll while selecting beyond side edges. |
| 563 model_->MoveCursorTo(event.location(), true); | 565 if (last_drag_location_.x() > 0 && last_drag_location_.x() < size().width()) { |
| 564 if (aggregated_clicks_ == 1) { | 566 drag_selection_timer_.Stop(); |
| 565 model_->SelectWord(); | 567 SelectThroughLastDragLocation(); |
| 566 // Expand the selection so the initially selected word remains selected. | 568 } else if (!drag_selection_timer_.IsRunning()) { |
| 567 gfx::Range selection = GetRenderText()->selection(); | 569 drag_selection_timer_.Start( |
| 568 const size_t min = std::min(selection.GetMin(), | 570 FROM_HERE, base::TimeDelta::FromMilliseconds(100), this, |
| 569 double_click_word_.GetMin()); | 571 &Textfield::SelectThroughLastDragLocation); |
| 570 const size_t max = std::max(selection.GetMax(), | |
| 571 double_click_word_.GetMax()); | |
| 572 const bool reversed = selection.is_reversed(); | |
| 573 selection.set_start(reversed ? max : min); | |
| 574 selection.set_end(reversed ? min : max); | |
| 575 model_->SelectRange(selection); | |
| 576 } | 572 } |
| 577 UpdateAfterChange(false, true); | 573 |
| 578 OnAfterUserAction(); | |
| 579 return true; | 574 return true; |
| 580 } | 575 } |
| 581 | 576 |
| 582 void Textfield::OnMouseReleased(const ui::MouseEvent& event) { | 577 void Textfield::OnMouseReleased(const ui::MouseEvent& event) { |
| 583 OnBeforeUserAction(); | 578 OnBeforeUserAction(); |
| 579 drag_selection_timer_.Stop(); | |
| 584 // Cancel suspected drag initiations, the user was clicking in the selection. | 580 // Cancel suspected drag initiations, the user was clicking in the selection. |
| 585 if (initiating_drag_) | 581 if (initiating_drag_) |
| 586 MoveCursorTo(event.location(), false); | 582 MoveCursorTo(event.location(), false); |
| 587 initiating_drag_ = false; | 583 initiating_drag_ = false; |
| 588 UpdateSelectionClipboard(); | 584 UpdateSelectionClipboard(); |
| 589 OnAfterUserAction(); | 585 OnAfterUserAction(); |
| 590 } | 586 } |
| 591 | 587 |
| 592 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) { | 588 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) { |
| 593 bool handled = controller_ && controller_->HandleKeyEvent(this, event); | 589 bool handled = controller_ && controller_->HandleKeyEvent(this, event); |
| (...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1535 render_text->DrawCursor(canvas, drop_cursor_position_); | 1531 render_text->DrawCursor(canvas, drop_cursor_position_); |
| 1536 | 1532 |
| 1537 canvas->Restore(); | 1533 canvas->Restore(); |
| 1538 } | 1534 } |
| 1539 | 1535 |
| 1540 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) { | 1536 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) { |
| 1541 if (model_->MoveCursorTo(point, select)) | 1537 if (model_->MoveCursorTo(point, select)) |
| 1542 UpdateAfterChange(false, true); | 1538 UpdateAfterChange(false, true); |
| 1543 } | 1539 } |
| 1544 | 1540 |
| 1541 void Textfield::SelectThroughLastDragLocation() { | |
| 1542 OnBeforeUserAction(); | |
| 1543 model_->MoveCursorTo(last_drag_location_, true); | |
|
Peter Kasting
2014/05/21 22:44:28
How does this work with off-Textfield cursor locat
msw
2014/05/21 23:15:10
Yes, that's how it works currently, and I think it
| |
| 1544 if (aggregated_clicks_ == 1) { | |
| 1545 model_->SelectWord(); | |
| 1546 // Expand the selection so the initially selected word remains selected. | |
| 1547 gfx::Range selection = GetRenderText()->selection(); | |
| 1548 const size_t min = std::min(selection.GetMin(), | |
| 1549 double_click_word_.GetMin()); | |
| 1550 const size_t max = std::max(selection.GetMax(), | |
| 1551 double_click_word_.GetMax()); | |
| 1552 const bool reversed = selection.is_reversed(); | |
| 1553 selection.set_start(reversed ? max : min); | |
| 1554 selection.set_end(reversed ? min : max); | |
| 1555 model_->SelectRange(selection); | |
| 1556 } | |
| 1557 UpdateAfterChange(false, true); | |
| 1558 OnAfterUserAction(); | |
| 1559 } | |
| 1560 | |
| 1545 void Textfield::OnCaretBoundsChanged() { | 1561 void Textfield::OnCaretBoundsChanged() { |
| 1546 if (GetInputMethod()) | 1562 if (GetInputMethod()) |
| 1547 GetInputMethod()->OnCaretBoundsChanged(this); | 1563 GetInputMethod()->OnCaretBoundsChanged(this); |
| 1548 if (touch_selection_controller_) | 1564 if (touch_selection_controller_) |
| 1549 touch_selection_controller_->SelectionChanged(); | 1565 touch_selection_controller_->SelectionChanged(); |
| 1550 } | 1566 } |
| 1551 | 1567 |
| 1552 void Textfield::OnBeforeUserAction() { | 1568 void Textfield::OnBeforeUserAction() { |
| 1553 DCHECK(!performing_user_action_); | 1569 DCHECK(!performing_user_action_); |
| 1554 performing_user_action_ = true; | 1570 performing_user_action_ = true; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1681 const size_t length = selection_clipboard_text.length(); | 1697 const size_t length = selection_clipboard_text.length(); |
| 1682 range = gfx::Range(range.start() + length, range.end() + length); | 1698 range = gfx::Range(range.start() + length, range.end() + length); |
| 1683 } | 1699 } |
| 1684 model_->MoveCursorTo(gfx::SelectionModel(range, affinity)); | 1700 model_->MoveCursorTo(gfx::SelectionModel(range, affinity)); |
| 1685 UpdateAfterChange(true, true); | 1701 UpdateAfterChange(true, true); |
| 1686 OnAfterUserAction(); | 1702 OnAfterUserAction(); |
| 1687 } | 1703 } |
| 1688 } | 1704 } |
| 1689 | 1705 |
| 1690 } // namespace views | 1706 } // namespace views |
| OLD | NEW |