| Index: ui/views/controls/textfield/textfield.cc
|
| diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc
|
| index 68aa01ec3bd832958bcc74db80c22734a5f3398c..0202b0fd694e1a11047a0258897dca591fa599de 100644
|
| --- a/ui/views/controls/textfield/textfield.cc
|
| +++ b/ui/views/controls/textfield/textfield.cc
|
| @@ -15,6 +15,7 @@
|
| #include "ui/base/dragdrop/drag_utils.h"
|
| #include "ui/base/resource/resource_bundle.h"
|
| #include "ui/base/ui_base_switches_util.h"
|
| +#include "ui/compositor/scoped_animation_duration_scale_mode.h"
|
| #include "ui/events/event.h"
|
| #include "ui/events/keycodes/keyboard_codes.h"
|
| #include "ui/gfx/canvas.h"
|
| @@ -63,6 +64,17 @@ void ConvertRectToScreen(const View* src, gfx::Rect* r) {
|
| r->set_origin(new_origin);
|
| }
|
|
|
| +// Get the drag selection timer delay, respecting animation scaling for testing.
|
| +int GetDragSelectionDelay() {
|
| + switch (ui::ScopedAnimationDurationScaleMode::duration_scale_mode()) {
|
| + case ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION: return 100;
|
| + case ui::ScopedAnimationDurationScaleMode::FAST_DURATION: return 25;
|
| + case ui::ScopedAnimationDurationScaleMode::SLOW_DURATION: return 400;
|
| + case ui::ScopedAnimationDurationScaleMode::ZERO_DURATION: return 0;
|
| + }
|
| + return 100;
|
| +}
|
| +
|
| int GetCommandForKeyEvent(const ui::KeyEvent& event, bool has_selection) {
|
| if (event.type() != ui::ET_KEY_PRESSED || event.IsUnicodeKeyCode())
|
| return kNoCommand;
|
| @@ -312,16 +324,16 @@ base::i18n::TextDirection Textfield::GetTextDirection() const {
|
| return GetRenderText()->GetTextDirection();
|
| }
|
|
|
| +base::string16 Textfield::GetSelectedText() const {
|
| + return model_->GetSelectedText();
|
| +}
|
| +
|
| void Textfield::SelectAll(bool reversed) {
|
| model_->SelectAll(reversed);
|
| UpdateSelectionClipboard();
|
| UpdateAfterChange(false, true);
|
| }
|
|
|
| -base::string16 Textfield::GetSelectedText() const {
|
| - return model_->GetSelectedText();
|
| -}
|
| -
|
| void Textfield::ClearSelection() {
|
| model_->ClearSelection();
|
| UpdateAfterChange(false, true);
|
| @@ -552,35 +564,32 @@ bool Textfield::OnMousePressed(const ui::MouseEvent& event) {
|
| }
|
|
|
| bool Textfield::OnMouseDragged(const ui::MouseEvent& event) {
|
| + last_drag_location_ = event.location();
|
| +
|
| // Don't adjust the cursor on a potential drag and drop, or if the mouse
|
| // movement from the last mouse click does not exceed the drag threshold.
|
| if (initiating_drag_ || !event.IsOnlyLeftMouseButton() ||
|
| - !ExceededDragThreshold(event.location() - last_click_location_)) {
|
| + !ExceededDragThreshold(last_drag_location_ - last_click_location_)) {
|
| return true;
|
| }
|
|
|
| - OnBeforeUserAction();
|
| - model_->MoveCursorTo(event.location(), true);
|
| - if (aggregated_clicks_ == 1) {
|
| - model_->SelectWord();
|
| - // Expand the selection so the initially selected word remains selected.
|
| - gfx::Range selection = GetRenderText()->selection();
|
| - const size_t min = std::min(selection.GetMin(),
|
| - double_click_word_.GetMin());
|
| - const size_t max = std::max(selection.GetMax(),
|
| - double_click_word_.GetMax());
|
| - const bool reversed = selection.is_reversed();
|
| - selection.set_start(reversed ? max : min);
|
| - selection.set_end(reversed ? min : max);
|
| - model_->SelectRange(selection);
|
| + // A timer is used to continuously scroll while selecting beyond side edges.
|
| + if ((event.location().x() > 0 && event.location().x() < size().width()) ||
|
| + GetDragSelectionDelay() == 0) {
|
| + drag_selection_timer_.Stop();
|
| + SelectThroughLastDragLocation();
|
| + } else if (!drag_selection_timer_.IsRunning()) {
|
| + drag_selection_timer_.Start(
|
| + FROM_HERE, base::TimeDelta::FromMilliseconds(GetDragSelectionDelay()),
|
| + this, &Textfield::SelectThroughLastDragLocation);
|
| }
|
| - UpdateAfterChange(false, true);
|
| - OnAfterUserAction();
|
| +
|
| return true;
|
| }
|
|
|
| void Textfield::OnMouseReleased(const ui::MouseEvent& event) {
|
| OnBeforeUserAction();
|
| + drag_selection_timer_.Stop();
|
| // Cancel suspected drag initiations, the user was clicking in the selection.
|
| if (initiating_drag_)
|
| MoveCursorTo(event.location(), false);
|
| @@ -1542,6 +1551,26 @@ void Textfield::MoveCursorTo(const gfx::Point& point, bool select) {
|
| UpdateAfterChange(false, true);
|
| }
|
|
|
| +void Textfield::SelectThroughLastDragLocation() {
|
| + OnBeforeUserAction();
|
| + model_->MoveCursorTo(last_drag_location_, true);
|
| + if (aggregated_clicks_ == 1) {
|
| + model_->SelectWord();
|
| + // Expand the selection so the initially selected word remains selected.
|
| + gfx::Range selection = GetRenderText()->selection();
|
| + const size_t min = std::min(selection.GetMin(),
|
| + double_click_word_.GetMin());
|
| + const size_t max = std::max(selection.GetMax(),
|
| + double_click_word_.GetMax());
|
| + const bool reversed = selection.is_reversed();
|
| + selection.set_start(reversed ? max : min);
|
| + selection.set_end(reversed ? min : max);
|
| + model_->SelectRange(selection);
|
| + }
|
| + UpdateAfterChange(false, true);
|
| + OnAfterUserAction();
|
| +}
|
| +
|
| void Textfield::OnCaretBoundsChanged() {
|
| if (GetInputMethod())
|
| GetInputMethod()->OnCaretBoundsChanged(this);
|
|
|