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

Side by Side Diff: ui/views/controls/textfield/textfield.cc

Issue 290733007: Make Textfield scroll continuously when dragging beyond edges. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove unnecessary test file changes. Created 6 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « ui/views/controls/textfield/textfield.h ('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 (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"
11 #include "ui/accessibility/ax_view_state.h" 11 #include "ui/accessibility/ax_view_state.h"
12 #include "ui/base/clipboard/scoped_clipboard_writer.h" 12 #include "ui/base/clipboard/scoped_clipboard_writer.h"
13 #include "ui/base/cursor/cursor.h" 13 #include "ui/base/cursor/cursor.h"
14 #include "ui/base/dragdrop/drag_drop_types.h" 14 #include "ui/base/dragdrop/drag_drop_types.h"
15 #include "ui/base/dragdrop/drag_utils.h" 15 #include "ui/base/dragdrop/drag_utils.h"
16 #include "ui/base/resource/resource_bundle.h" 16 #include "ui/base/resource/resource_bundle.h"
17 #include "ui/base/ui_base_switches_util.h" 17 #include "ui/base/ui_base_switches_util.h"
18 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
18 #include "ui/events/event.h" 19 #include "ui/events/event.h"
19 #include "ui/events/keycodes/keyboard_codes.h" 20 #include "ui/events/keycodes/keyboard_codes.h"
20 #include "ui/gfx/canvas.h" 21 #include "ui/gfx/canvas.h"
21 #include "ui/gfx/display.h" 22 #include "ui/gfx/display.h"
22 #include "ui/gfx/insets.h" 23 #include "ui/gfx/insets.h"
23 #include "ui/gfx/screen.h" 24 #include "ui/gfx/screen.h"
24 #include "ui/native_theme/native_theme.h" 25 #include "ui/native_theme/native_theme.h"
25 #include "ui/views/background.h" 26 #include "ui/views/background.h"
26 #include "ui/views/controls/focusable_border.h" 27 #include "ui/views/controls/focusable_border.h"
27 #include "ui/views/controls/label.h" 28 #include "ui/views/controls/label.h"
(...skipping 28 matching lines...) Expand all
56 const int kNoCommand = 0; 57 const int kNoCommand = 0;
57 58
58 void ConvertRectToScreen(const View* src, gfx::Rect* r) { 59 void ConvertRectToScreen(const View* src, gfx::Rect* r) {
59 DCHECK(src); 60 DCHECK(src);
60 61
61 gfx::Point new_origin = r->origin(); 62 gfx::Point new_origin = r->origin();
62 View::ConvertPointToScreen(src, &new_origin); 63 View::ConvertPointToScreen(src, &new_origin);
63 r->set_origin(new_origin); 64 r->set_origin(new_origin);
64 } 65 }
65 66
67 // Get the drag selection timer delay, respecting animation scaling for testing.
68 int GetDragSelectionDelay() {
69 switch (ui::ScopedAnimationDurationScaleMode::duration_scale_mode()) {
70 case ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION: return 100;
71 case ui::ScopedAnimationDurationScaleMode::FAST_DURATION: return 25;
72 case ui::ScopedAnimationDurationScaleMode::SLOW_DURATION: return 400;
73 case ui::ScopedAnimationDurationScaleMode::ZERO_DURATION: return 0;
74 }
75 return 100;
76 }
77
66 int GetCommandForKeyEvent(const ui::KeyEvent& event, bool has_selection) { 78 int GetCommandForKeyEvent(const ui::KeyEvent& event, bool has_selection) {
67 if (event.type() != ui::ET_KEY_PRESSED || event.IsUnicodeKeyCode()) 79 if (event.type() != ui::ET_KEY_PRESSED || event.IsUnicodeKeyCode())
68 return kNoCommand; 80 return kNoCommand;
69 81
70 const bool shift = event.IsShiftDown(); 82 const bool shift = event.IsShiftDown();
71 const bool control = event.IsControlDown(); 83 const bool control = event.IsControlDown();
72 const bool alt = event.IsAltDown() || event.IsAltGrDown(); 84 const bool alt = event.IsAltDown() || event.IsAltGrDown();
73 switch (event.key_code()) { 85 switch (event.key_code()) {
74 case ui::VKEY_Z: 86 case ui::VKEY_Z:
75 if (control && !shift && !alt) 87 if (control && !shift && !alt)
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 return; 317 return;
306 model_->InsertText(new_text); 318 model_->InsertText(new_text);
307 OnCaretBoundsChanged(); 319 OnCaretBoundsChanged();
308 SchedulePaint(); 320 SchedulePaint();
309 } 321 }
310 322
311 base::i18n::TextDirection Textfield::GetTextDirection() const { 323 base::i18n::TextDirection Textfield::GetTextDirection() const {
312 return GetRenderText()->GetTextDirection(); 324 return GetRenderText()->GetTextDirection();
313 } 325 }
314 326
327 base::string16 Textfield::GetSelectedText() const {
328 return model_->GetSelectedText();
329 }
330
315 void Textfield::SelectAll(bool reversed) { 331 void Textfield::SelectAll(bool reversed) {
316 model_->SelectAll(reversed); 332 model_->SelectAll(reversed);
317 UpdateSelectionClipboard(); 333 UpdateSelectionClipboard();
318 UpdateAfterChange(false, true); 334 UpdateAfterChange(false, true);
319 } 335 }
320 336
321 base::string16 Textfield::GetSelectedText() const {
322 return model_->GetSelectedText();
323 }
324
325 void Textfield::ClearSelection() { 337 void Textfield::ClearSelection() {
326 model_->ClearSelection(); 338 model_->ClearSelection();
327 UpdateAfterChange(false, true); 339 UpdateAfterChange(false, true);
328 } 340 }
329 341
330 bool Textfield::HasSelection() const { 342 bool Textfield::HasSelection() const {
331 return !GetSelectedRange().is_empty(); 343 return !GetSelectedRange().is_empty();
332 } 344 }
333 345
334 SkColor Textfield::GetTextColor() const { 346 SkColor Textfield::GetTextColor() const {
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 PasteSelectionClipboard(event); 557 PasteSelectionClipboard(event);
546 } 558 }
547 } 559 }
548 #endif 560 #endif
549 } 561 }
550 562
551 return true; 563 return true;
552 } 564 }
553 565
554 bool Textfield::OnMouseDragged(const ui::MouseEvent& event) { 566 bool Textfield::OnMouseDragged(const ui::MouseEvent& event) {
567 last_drag_location_ = event.location();
568
555 // Don't adjust the cursor on a potential drag and drop, or if the mouse 569 // 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. 570 // movement from the last mouse click does not exceed the drag threshold.
557 if (initiating_drag_ || !event.IsOnlyLeftMouseButton() || 571 if (initiating_drag_ || !event.IsOnlyLeftMouseButton() ||
558 !ExceededDragThreshold(event.location() - last_click_location_)) { 572 !ExceededDragThreshold(last_drag_location_ - last_click_location_)) {
559 return true; 573 return true;
560 } 574 }
561 575
562 OnBeforeUserAction(); 576 // A timer is used to continuously scroll while selecting beyond side edges.
563 model_->MoveCursorTo(event.location(), true); 577 if ((event.location().x() > 0 && event.location().x() < size().width()) ||
564 if (aggregated_clicks_ == 1) { 578 GetDragSelectionDelay() == 0) {
565 model_->SelectWord(); 579 drag_selection_timer_.Stop();
566 // Expand the selection so the initially selected word remains selected. 580 SelectThroughLastDragLocation();
567 gfx::Range selection = GetRenderText()->selection(); 581 } else if (!drag_selection_timer_.IsRunning()) {
568 const size_t min = std::min(selection.GetMin(), 582 drag_selection_timer_.Start(
569 double_click_word_.GetMin()); 583 FROM_HERE, base::TimeDelta::FromMilliseconds(GetDragSelectionDelay()),
570 const size_t max = std::max(selection.GetMax(), 584 this, &Textfield::SelectThroughLastDragLocation);
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 } 585 }
577 UpdateAfterChange(false, true); 586
578 OnAfterUserAction();
579 return true; 587 return true;
580 } 588 }
581 589
582 void Textfield::OnMouseReleased(const ui::MouseEvent& event) { 590 void Textfield::OnMouseReleased(const ui::MouseEvent& event) {
583 OnBeforeUserAction(); 591 OnBeforeUserAction();
592 drag_selection_timer_.Stop();
584 // Cancel suspected drag initiations, the user was clicking in the selection. 593 // Cancel suspected drag initiations, the user was clicking in the selection.
585 if (initiating_drag_) 594 if (initiating_drag_)
586 MoveCursorTo(event.location(), false); 595 MoveCursorTo(event.location(), false);
587 initiating_drag_ = false; 596 initiating_drag_ = false;
588 UpdateSelectionClipboard(); 597 UpdateSelectionClipboard();
589 OnAfterUserAction(); 598 OnAfterUserAction();
590 } 599 }
591 600
592 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) { 601 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) {
593 bool handled = controller_ && controller_->HandleKeyEvent(this, event); 602 bool handled = controller_ && controller_->HandleKeyEvent(this, event);
(...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after
1535 render_text->DrawCursor(canvas, drop_cursor_position_); 1544 render_text->DrawCursor(canvas, drop_cursor_position_);
1536 1545
1537 canvas->Restore(); 1546 canvas->Restore();
1538 } 1547 }
1539 1548
1540 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) { 1549 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) {
1541 if (model_->MoveCursorTo(point, select)) 1550 if (model_->MoveCursorTo(point, select))
1542 UpdateAfterChange(false, true); 1551 UpdateAfterChange(false, true);
1543 } 1552 }
1544 1553
1554 void Textfield::SelectThroughLastDragLocation() {
1555 OnBeforeUserAction();
1556 model_->MoveCursorTo(last_drag_location_, true);
1557 if (aggregated_clicks_ == 1) {
1558 model_->SelectWord();
1559 // Expand the selection so the initially selected word remains selected.
1560 gfx::Range selection = GetRenderText()->selection();
1561 const size_t min = std::min(selection.GetMin(),
1562 double_click_word_.GetMin());
1563 const size_t max = std::max(selection.GetMax(),
1564 double_click_word_.GetMax());
1565 const bool reversed = selection.is_reversed();
1566 selection.set_start(reversed ? max : min);
1567 selection.set_end(reversed ? min : max);
1568 model_->SelectRange(selection);
1569 }
1570 UpdateAfterChange(false, true);
1571 OnAfterUserAction();
1572 }
1573
1545 void Textfield::OnCaretBoundsChanged() { 1574 void Textfield::OnCaretBoundsChanged() {
1546 if (GetInputMethod()) 1575 if (GetInputMethod())
1547 GetInputMethod()->OnCaretBoundsChanged(this); 1576 GetInputMethod()->OnCaretBoundsChanged(this);
1548 if (touch_selection_controller_) 1577 if (touch_selection_controller_)
1549 touch_selection_controller_->SelectionChanged(); 1578 touch_selection_controller_->SelectionChanged();
1550 } 1579 }
1551 1580
1552 void Textfield::OnBeforeUserAction() { 1581 void Textfield::OnBeforeUserAction() {
1553 DCHECK(!performing_user_action_); 1582 DCHECK(!performing_user_action_);
1554 performing_user_action_ = true; 1583 performing_user_action_ = true;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1681 const size_t length = selection_clipboard_text.length(); 1710 const size_t length = selection_clipboard_text.length();
1682 range = gfx::Range(range.start() + length, range.end() + length); 1711 range = gfx::Range(range.start() + length, range.end() + length);
1683 } 1712 }
1684 model_->MoveCursorTo(gfx::SelectionModel(range, affinity)); 1713 model_->MoveCursorTo(gfx::SelectionModel(range, affinity));
1685 UpdateAfterChange(true, true); 1714 UpdateAfterChange(true, true);
1686 OnAfterUserAction(); 1715 OnAfterUserAction();
1687 } 1716 }
1688 } 1717 }
1689 1718
1690 } // namespace views 1719 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/textfield/textfield.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698