Chromium Code Reviews| 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 2d7b6152073a1d0b13c7a01bbbc2eb4aa6236271..bab1c6f53a762d7c26bb0b142a3844cf768b23d5 100644 |
| --- a/views/controls/textfield/native_textfield_views.cc |
| +++ b/views/controls/textfield/native_textfield_views.cc |
| @@ -67,6 +67,7 @@ NativeTextfieldViews::NativeTextfieldViews(Textfield* parent) |
| text_offset_(0), |
| insert_(true), |
| is_cursor_visible_(false), |
| + is_drop_cursor_visible_(false), |
| skip_input_method_cancel_composition_(false), |
| initiating_drag_(false), |
| ALLOW_THIS_IN_INITIALIZER_LIST(cursor_timer_(this)), |
| @@ -177,10 +178,14 @@ 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; |
| + drop_cursor_bounds_ = GetCursorBounds(FindCursorPosition(event.location())); |
| + 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; |
| @@ -223,6 +228,7 @@ int NativeTextfieldViews::OnPerformDrop(const DropTargetEvent& event) { |
| void NativeTextfieldViews::OnDragDone() { |
| initiating_drag_ = false; |
| + is_drop_cursor_visible_ = false; |
| } |
| void NativeTextfieldViews::OnPaint(gfx::Canvas* canvas) { |
| @@ -755,33 +761,35 @@ void NativeTextfieldViews::RepaintCursor() { |
| SchedulePaintInRect(r); |
| } |
| +gfx::Rect NativeTextfieldViews::GetCursorBounds(size_t cursor_pos) const { |
| + string16 text = model_->GetVisibleText(); |
| + const gfx::Font& font = GetFont(); |
| + int x = font.GetStringWidth(text.substr(0U, cursor_pos)); |
| + DCHECK(x >= 0); |
|
oshima
2011/06/07 17:32:52
can you change to DCHECK_GE?
msw
2011/06/08 23:50:29
Done.
|
| + int h = std::min(height() - GetInsets().height(), font.GetHeight()); |
| + gfx::Rect bounds(x, (height() - h) / 2, 0, h); |
| + if (text.length() != cursor_pos) |
| + bounds.set_width(font.GetStringWidth(text.substr(0, cursor_pos + 1)) - x); |
| + return bounds; |
| +} |
| + |
| + |
| void NativeTextfieldViews::UpdateCursorBoundsAndTextOffset() { |
| if (bounds().IsEmpty()) |
| return; |
| - gfx::Insets insets = GetInsets(); |
| - |
| - int width = bounds().width() - insets.width(); |
| - |
| // 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(model_->cursor_pos()); |
| 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) { |
| @@ -792,7 +800,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(); |
| } |
| @@ -839,14 +847,21 @@ 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. |
| - canvas->DrawRectInt(kCursorColor, |
| - cursor_bounds_.x(), |
| - cursor_bounds_.y(), |
| - insert_ ? 0 : cursor_bounds_.width(), |
| - cursor_bounds_.height()); |
| + if (textfield_->IsEnabled()) { |
| + // Paint cursor. Replace cursor is drawn as rectangle for now. |
| + if (is_cursor_visible_ && !model_->HasSelection()) |
| + canvas->DrawRectInt(kCursorColor, |
| + cursor_bounds_.x(), |
| + cursor_bounds_.y(), |
| + insert_ ? 0 : cursor_bounds_.width(), |
| + cursor_bounds_.height()); |
| + // Paint drop cursor. |
| + if (is_drop_cursor_visible_) |
| + canvas->DrawRectInt(kCursorColor, |
| + drop_cursor_bounds_.x(), |
| + drop_cursor_bounds_.y(), |
| + 0, |
| + drop_cursor_bounds_.height()); |
|
oshima
2011/06/07 17:32:52
basic question. Can both be visible at the same ti
msw
2011/06/08 23:50:29
Done.
|
| } |
| } |