| Index: views/controls/textfield/native_textfield_views.cc
|
| diff --git a/views/controls/textfield/native_textfield_views.cc b/views/controls/textfield/native_textfield_views.cc
|
| index 911c519228c46767cf32f73ad7840e2da81812c4..22049133302d560c4234cc4349a8d4fb2c121d26 100644
|
| --- a/views/controls/textfield/native_textfield_views.cc
|
| +++ b/views/controls/textfield/native_textfield_views.cc
|
| @@ -179,10 +179,15 @@ bool NativeTextfieldViews::CanDrop(const OSExchangeData& data) {
|
| }
|
|
|
| int NativeTextfieldViews::OnDragUpdated(const DropTargetEvent& event) {
|
| - // TODO(msw): retain unfocused selection, render secondary cursor...
|
| DCHECK(CanDrop(event.data()));
|
| + bool is_point_in_selection = IsPointInSelection(event.location());
|
| + is_drop_cursor_visible_ = !is_point_in_selection;
|
| + // TODO(msw): Pan over text when the user drags to the visible text edge.
|
| + UpdateCursorBoundsAndTextOffset(FindCursorPosition(event.location()), true);
|
| + SchedulePaint();
|
| +
|
| if (initiating_drag_) {
|
| - if (IsPointInSelection(event.location()))
|
| + if (is_point_in_selection)
|
| return ui::DragDropTypes::DRAG_NONE;
|
| return event.IsControlDown() ? ui::DragDropTypes::DRAG_COPY :
|
| ui::DragDropTypes::DRAG_MOVE;
|
| @@ -225,6 +230,7 @@ int NativeTextfieldViews::OnPerformDrop(const DropTargetEvent& event) {
|
|
|
| void NativeTextfieldViews::OnDragDone() {
|
| initiating_drag_ = false;
|
| + is_drop_cursor_visible_ = false;
|
| }
|
|
|
| void NativeTextfieldViews::OnPaint(gfx::Canvas* canvas) {
|
| @@ -302,7 +308,7 @@ string16 NativeTextfieldViews::GetText() const {
|
|
|
| void NativeTextfieldViews::UpdateText() {
|
| model_->SetText(textfield_->text());
|
| - UpdateCursorBoundsAndTextOffset();
|
| + UpdateCursorBoundsAndTextOffset(model_->cursor_pos(), insert_);
|
| SchedulePaint();
|
| }
|
|
|
| @@ -310,7 +316,7 @@ void NativeTextfieldViews::AppendText(const string16& text) {
|
| if (text.empty())
|
| return;
|
| model_->Append(text);
|
| - UpdateCursorBoundsAndTextOffset();
|
| + UpdateCursorBoundsAndTextOffset(model_->cursor_pos(), insert_);
|
| SchedulePaint();
|
| }
|
|
|
| @@ -356,12 +362,12 @@ void NativeTextfieldViews::UpdateReadOnly() {
|
| }
|
|
|
| void NativeTextfieldViews::UpdateFont() {
|
| - UpdateCursorBoundsAndTextOffset();
|
| + UpdateCursorBoundsAndTextOffset(model_->cursor_pos(), insert_);
|
| }
|
|
|
| void NativeTextfieldViews::UpdateIsPassword() {
|
| model_->set_is_password(textfield_->IsPassword());
|
| - UpdateCursorBoundsAndTextOffset();
|
| + UpdateCursorBoundsAndTextOffset(model_->cursor_pos(), insert_);
|
| SchedulePaint();
|
| OnTextInputTypeChanged();
|
| }
|
| @@ -383,7 +389,7 @@ void NativeTextfieldViews::UpdateHorizontalMargins() {
|
| gfx::Insets inset = GetInsets();
|
|
|
| text_border_->SetInsets(inset.top(), left, inset.bottom(), right);
|
| - UpdateCursorBoundsAndTextOffset();
|
| + UpdateCursorBoundsAndTextOffset(model_->cursor_pos(), insert_);
|
| }
|
|
|
| void NativeTextfieldViews::UpdateVerticalMargins() {
|
| @@ -393,7 +399,7 @@ void NativeTextfieldViews::UpdateVerticalMargins() {
|
| gfx::Insets inset = GetInsets();
|
|
|
| text_border_->SetInsets(top, inset.left(), bottom, inset.right());
|
| - UpdateCursorBoundsAndTextOffset();
|
| + UpdateCursorBoundsAndTextOffset(model_->cursor_pos(), insert_);
|
| }
|
|
|
| bool NativeTextfieldViews::SetFocus() {
|
| @@ -419,7 +425,7 @@ void NativeTextfieldViews::GetSelectedRange(ui::Range* range) const {
|
|
|
| void NativeTextfieldViews::SelectRange(const ui::Range& range) {
|
| model_->SelectRange(range);
|
| - UpdateCursorBoundsAndTextOffset();
|
| + UpdateCursorBoundsAndTextOffset(model_->cursor_pos(), insert_);
|
| SchedulePaint();
|
| }
|
|
|
| @@ -564,7 +570,7 @@ void NativeTextfieldViews::SetEnableTextfieldViews(bool enabled) {
|
| }
|
|
|
| void NativeTextfieldViews::OnBoundsChanged(const gfx::Rect& previous_bounds) {
|
| - UpdateCursorBoundsAndTextOffset();
|
| + UpdateCursorBoundsAndTextOffset(model_->cursor_pos(), insert_);
|
| }
|
|
|
|
|
| @@ -761,33 +767,37 @@ void NativeTextfieldViews::RepaintCursor() {
|
| SchedulePaintInRect(r);
|
| }
|
|
|
| -void NativeTextfieldViews::UpdateCursorBoundsAndTextOffset() {
|
| - if (bounds().IsEmpty())
|
| - return;
|
| +gfx::Rect NativeTextfieldViews::GetCursorBounds(size_t cursor_pos,
|
| + bool insert_mode) const {
|
| + string16 text = model_->GetVisibleText();
|
| + const gfx::Font& font = GetFont();
|
| + int x = font.GetStringWidth(text.substr(0U, cursor_pos));
|
| + DCHECK_GE(x, 0);
|
| + int h = std::min(height() - GetInsets().height(), font.GetHeight());
|
| + gfx::Rect bounds(x, (height() - h) / 2, 0, h);
|
| + if (!insert_mode && text.length() != cursor_pos)
|
| + bounds.set_width(font.GetStringWidth(text.substr(0, cursor_pos + 1)) - x);
|
| + return bounds;
|
| +}
|
|
|
| - gfx::Insets insets = GetInsets();
|
|
|
| - int width = bounds().width() - insets.width();
|
| +void NativeTextfieldViews::UpdateCursorBoundsAndTextOffset(size_t cursor_pos,
|
| + bool insert_mode) {
|
| + if (bounds().IsEmpty())
|
| + return;
|
|
|
| // TODO(oshima): bidi
|
| - const gfx::Font& font = GetFont();
|
| - int full_width = font.GetStringWidth(model_->GetVisibleText());
|
| - int cursor_height = std::min(height() - insets.height(), font.GetHeight());
|
| -
|
| - cursor_bounds_ = model_->GetCursorBounds(font);
|
| - cursor_bounds_.set_y((height() - cursor_height) / 2);
|
| - cursor_bounds_.set_height(cursor_height);
|
| -
|
| - int x_right = text_offset_ + cursor_bounds_.right();
|
| - int x_left = text_offset_ + cursor_bounds_.x();
|
| + int width = bounds().width() - GetInsets().width();
|
| + int full_width = GetFont().GetStringWidth(model_->GetVisibleText());
|
| + cursor_bounds_ = GetCursorBounds(cursor_pos, insert_mode);
|
|
|
| if (full_width < width) {
|
| // Show all text whenever the text fits to the size.
|
| text_offset_ = 0;
|
| - } else if (x_right > width) {
|
| + } else if ((text_offset_ + cursor_bounds_.right()) > width) {
|
| // when the cursor overflows to the right
|
| text_offset_ = width - cursor_bounds_.right();
|
| - } else if (x_left < 0) {
|
| + } else if ((text_offset_ + cursor_bounds_.x()) < 0) {
|
| // when the cursor overflows to the left
|
| text_offset_ = -cursor_bounds_.x();
|
| } else if (full_width > width && text_offset_ + full_width < width) {
|
| @@ -798,7 +808,7 @@ void NativeTextfieldViews::UpdateCursorBoundsAndTextOffset() {
|
| // move cursor freely.
|
| }
|
| // shift cursor bounds to fit insets.
|
| - cursor_bounds_.set_x(cursor_bounds_.x() + text_offset_ + insets.left());
|
| + cursor_bounds_.set_x(cursor_bounds_.x() + text_offset_ + GetInsets().left());
|
|
|
| OnCaretBoundsChanged();
|
| }
|
| @@ -846,15 +856,14 @@ void NativeTextfieldViews::PaintTextAndCursor(gfx::Canvas* canvas) {
|
| }
|
| canvas->Restore();
|
|
|
| - if (textfield_->IsEnabled() && is_cursor_visible_ &&
|
| - !model_->HasSelection()) {
|
| - // Paint Cursor. Replace cursor is drawn as rectangle for now.
|
| + // Paint cursor. Replace cursor is drawn as rectangle for now.
|
| + if (textfield_->IsEnabled() && (is_drop_cursor_visible_ ||
|
| + (is_cursor_visible_ && !model_->HasSelection())))
|
| canvas->DrawRectInt(kCursorColor,
|
| cursor_bounds_.x(),
|
| cursor_bounds_.y(),
|
| - insert_ ? 0 : cursor_bounds_.width(),
|
| + cursor_bounds_.width(),
|
| cursor_bounds_.height());
|
| - }
|
| }
|
|
|
| bool NativeTextfieldViews::HandleKeyEvent(const KeyEvent& key_event) {
|
| @@ -1015,7 +1024,7 @@ bool NativeTextfieldViews::IsPointInSelection(const gfx::Point& point) const {
|
| bool NativeTextfieldViews::MoveCursorTo(const gfx::Point& point, bool select) {
|
| size_t pos = FindCursorPosition(point);
|
| if (model_->MoveCursorTo(pos, select)) {
|
| - UpdateCursorBoundsAndTextOffset();
|
| + UpdateCursorBoundsAndTextOffset(model_->cursor_pos(), insert_);
|
| return true;
|
| }
|
| return false;
|
| @@ -1034,7 +1043,7 @@ void NativeTextfieldViews::UpdateAfterChange(bool text_changed,
|
| RepaintCursor();
|
| }
|
| if (text_changed || cursor_changed) {
|
| - UpdateCursorBoundsAndTextOffset();
|
| + UpdateCursorBoundsAndTextOffset(model_->cursor_pos(), insert_);
|
| SchedulePaint();
|
| }
|
| }
|
|
|