| 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 int Textfield::GetBaseline() const { | 305 int Textfield::GetBaseline() const { |
| 306 return GetInsets().top() + GetRenderText()->GetBaseline(); | 306 return GetInsets().top() + GetRenderText()->GetBaseline(); |
| 307 } | 307 } |
| 308 | 308 |
| 309 gfx::Size Textfield::GetPreferredSize() { | 309 gfx::Size Textfield::GetPreferredSize() { |
| 310 const gfx::Insets& insets = GetInsets(); | 310 const gfx::Insets& insets = GetInsets(); |
| 311 return gfx::Size(GetFontList().GetExpectedTextWidth(default_width_in_chars_) + | 311 return gfx::Size(GetFontList().GetExpectedTextWidth(default_width_in_chars_) + |
| 312 insets.width(), GetFontList().GetHeight() + insets.height()); | 312 insets.width(), GetFontList().GetHeight() + insets.height()); |
| 313 } | 313 } |
| 314 | 314 |
| 315 void Textfield::AboutToRequestFocusFromTabTraversal(bool reverse) { | 315 const char* Textfield::GetClassName() const { |
| 316 SelectAll(false); | 316 return kViewClassName; |
| 317 } | 317 } |
| 318 | 318 |
| 319 bool Textfield::SkipDefaultKeyEventProcessing(const ui::KeyEvent& e) { | 319 gfx::NativeCursor Textfield::GetCursor(const ui::MouseEvent& event) { |
| 320 // Skip any accelerator handling of backspace; textfields handle this key. | 320 bool in_selection = GetRenderText()->IsPointInSelection(event.location()); |
| 321 // Also skip processing Windows [Alt]+<num-pad digit> Unicode alt-codes. | 321 bool drag_event = event.type() == ui::ET_MOUSE_DRAGGED; |
| 322 return e.key_code() == ui::VKEY_BACK || e.IsUnicodeKeyCode(); | 322 bool text_cursor = !initiating_drag_ && (drag_event || !in_selection); |
| 323 return text_cursor ? ui::kCursorIBeam : ui::kCursorNull; |
| 323 } | 324 } |
| 324 | 325 |
| 325 void Textfield::OnPaint(gfx::Canvas* canvas) { | 326 bool Textfield::OnMousePressed(const ui::MouseEvent& event) { |
| 326 OnPaintBackground(canvas); | 327 TrackMouseClicks(event); |
| 327 PaintTextAndCursor(canvas); | 328 |
| 328 OnPaintBorder(canvas); | 329 if (!controller_ || !controller_->HandleMouseEvent(this, event)) { |
| 329 if (NativeViewHost::kRenderNativeControlFocus) | 330 if (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) { |
| 330 Painter::PaintFocusPainter(this, canvas, focus_painter_.get()); | 331 RequestFocus(); |
| 332 ShowImeIfNeeded(); |
| 333 } |
| 334 |
| 335 if (event.IsOnlyLeftMouseButton()) { |
| 336 OnBeforeUserAction(); |
| 337 initiating_drag_ = false; |
| 338 switch (aggregated_clicks_) { |
| 339 case 0: |
| 340 if (GetRenderText()->IsPointInSelection(event.location())) |
| 341 initiating_drag_ = true; |
| 342 else |
| 343 MoveCursorTo(event.location(), event.IsShiftDown()); |
| 344 break; |
| 345 case 1: |
| 346 model_->MoveCursorTo(event.location(), false); |
| 347 model_->SelectWord(); |
| 348 UpdateAfterChange(false, true); |
| 349 double_click_word_ = GetRenderText()->selection(); |
| 350 break; |
| 351 case 2: |
| 352 SelectAll(false); |
| 353 break; |
| 354 default: |
| 355 NOTREACHED(); |
| 356 } |
| 357 OnAfterUserAction(); |
| 358 } |
| 359 |
| 360 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 361 if (event.IsOnlyMiddleMouseButton()) { |
| 362 if (GetRenderText()->IsPointInSelection(event.location())) { |
| 363 OnBeforeUserAction(); |
| 364 ClearSelection(); |
| 365 ui::ScopedClipboardWriter( |
| 366 ui::Clipboard::GetForCurrentThread(), |
| 367 ui::CLIPBOARD_TYPE_SELECTION).WriteText(base::string16()); |
| 368 OnAfterUserAction(); |
| 369 } else if(!read_only()) { |
| 370 PasteSelectionClipboard(event); |
| 371 } |
| 372 } |
| 373 #endif |
| 374 } |
| 375 |
| 376 touch_selection_controller_.reset(); |
| 377 return true; |
| 378 } |
| 379 |
| 380 bool Textfield::OnMouseDragged(const ui::MouseEvent& event) { |
| 381 // Don't adjust the cursor on a potential drag and drop, or if the mouse |
| 382 // movement from the last mouse click does not exceed the drag threshold. |
| 383 if (initiating_drag_ || !event.IsOnlyLeftMouseButton() || |
| 384 !ExceededDragThreshold(event.location() - last_click_location_)) { |
| 385 return true; |
| 386 } |
| 387 |
| 388 OnBeforeUserAction(); |
| 389 model_->MoveCursorTo(event.location(), true); |
| 390 if (aggregated_clicks_ == 1) { |
| 391 model_->SelectWord(); |
| 392 // Expand the selection so the initially selected word remains selected. |
| 393 gfx::Range selection = GetRenderText()->selection(); |
| 394 const size_t min = std::min(selection.GetMin(), |
| 395 double_click_word_.GetMin()); |
| 396 const size_t max = std::max(selection.GetMax(), |
| 397 double_click_word_.GetMax()); |
| 398 const bool reversed = selection.is_reversed(); |
| 399 selection.set_start(reversed ? max : min); |
| 400 selection.set_end(reversed ? min : max); |
| 401 model_->SelectRange(selection); |
| 402 } |
| 403 UpdateAfterChange(false, true); |
| 404 OnAfterUserAction(); |
| 405 return true; |
| 406 } |
| 407 |
| 408 void Textfield::OnMouseReleased(const ui::MouseEvent& event) { |
| 409 OnBeforeUserAction(); |
| 410 // Cancel suspected drag initiations, the user was clicking in the selection. |
| 411 if (initiating_drag_) |
| 412 MoveCursorTo(event.location(), false); |
| 413 initiating_drag_ = false; |
| 414 UpdateSelectionClipboard(); |
| 415 OnAfterUserAction(); |
| 331 } | 416 } |
| 332 | 417 |
| 333 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) { | 418 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) { |
| 334 bool handled = controller_ && controller_->HandleKeyEvent(this, event); | 419 bool handled = controller_ && controller_->HandleKeyEvent(this, event); |
| 335 touch_selection_controller_.reset(); | 420 touch_selection_controller_.reset(); |
| 336 if (handled) | 421 if (handled) |
| 337 return true; | 422 return true; |
| 338 | 423 |
| 339 // TODO(oshima): Refactor and consolidate with ExecuteCommand. | 424 // TODO(oshima): Refactor and consolidate with ExecuteCommand. |
| 340 if (event.type() == ui::ET_KEY_PRESSED) { | 425 if (event.type() == ui::ET_KEY_PRESSED) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 | 536 |
| 452 // We must have input method in order to support text input. | 537 // We must have input method in order to support text input. |
| 453 DCHECK(GetInputMethod()); | 538 DCHECK(GetInputMethod()); |
| 454 UpdateAfterChange(text_changed, cursor_changed); | 539 UpdateAfterChange(text_changed, cursor_changed); |
| 455 OnAfterUserAction(); | 540 OnAfterUserAction(); |
| 456 return (text_changed || cursor_changed); | 541 return (text_changed || cursor_changed); |
| 457 } | 542 } |
| 458 return false; | 543 return false; |
| 459 } | 544 } |
| 460 | 545 |
| 461 bool Textfield::OnMousePressed(const ui::MouseEvent& event) { | |
| 462 TrackMouseClicks(event); | |
| 463 | |
| 464 if (!controller_ || !controller_->HandleMouseEvent(this, event)) { | |
| 465 if (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) { | |
| 466 RequestFocus(); | |
| 467 ShowImeIfNeeded(); | |
| 468 } | |
| 469 | |
| 470 if (event.IsOnlyLeftMouseButton()) { | |
| 471 OnBeforeUserAction(); | |
| 472 initiating_drag_ = false; | |
| 473 switch (aggregated_clicks_) { | |
| 474 case 0: | |
| 475 if (GetRenderText()->IsPointInSelection(event.location())) | |
| 476 initiating_drag_ = true; | |
| 477 else | |
| 478 MoveCursorTo(event.location(), event.IsShiftDown()); | |
| 479 break; | |
| 480 case 1: | |
| 481 model_->MoveCursorTo(event.location(), false); | |
| 482 model_->SelectWord(); | |
| 483 UpdateAfterChange(false, true); | |
| 484 double_click_word_ = GetRenderText()->selection(); | |
| 485 break; | |
| 486 case 2: | |
| 487 SelectAll(false); | |
| 488 break; | |
| 489 default: | |
| 490 NOTREACHED(); | |
| 491 } | |
| 492 OnAfterUserAction(); | |
| 493 } | |
| 494 | |
| 495 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | |
| 496 if (event.IsOnlyMiddleMouseButton()) { | |
| 497 if (GetRenderText()->IsPointInSelection(event.location())) { | |
| 498 OnBeforeUserAction(); | |
| 499 ClearSelection(); | |
| 500 ui::ScopedClipboardWriter( | |
| 501 ui::Clipboard::GetForCurrentThread(), | |
| 502 ui::CLIPBOARD_TYPE_SELECTION).WriteText(base::string16()); | |
| 503 OnAfterUserAction(); | |
| 504 } else if(!read_only()) { | |
| 505 PasteSelectionClipboard(event); | |
| 506 } | |
| 507 } | |
| 508 #endif | |
| 509 } | |
| 510 | |
| 511 touch_selection_controller_.reset(); | |
| 512 return true; | |
| 513 } | |
| 514 | |
| 515 bool Textfield::OnMouseDragged(const ui::MouseEvent& event) { | |
| 516 // Don't adjust the cursor on a potential drag and drop, or if the mouse | |
| 517 // movement from the last mouse click does not exceed the drag threshold. | |
| 518 if (initiating_drag_ || !event.IsOnlyLeftMouseButton() || | |
| 519 !ExceededDragThreshold(event.location() - last_click_location_)) { | |
| 520 return true; | |
| 521 } | |
| 522 | |
| 523 OnBeforeUserAction(); | |
| 524 model_->MoveCursorTo(event.location(), true); | |
| 525 if (aggregated_clicks_ == 1) { | |
| 526 model_->SelectWord(); | |
| 527 // Expand the selection so the initially selected word remains selected. | |
| 528 gfx::Range selection = GetRenderText()->selection(); | |
| 529 const size_t min = std::min(selection.GetMin(), | |
| 530 double_click_word_.GetMin()); | |
| 531 const size_t max = std::max(selection.GetMax(), | |
| 532 double_click_word_.GetMax()); | |
| 533 const bool reversed = selection.is_reversed(); | |
| 534 selection.set_start(reversed ? max : min); | |
| 535 selection.set_end(reversed ? min : max); | |
| 536 model_->SelectRange(selection); | |
| 537 } | |
| 538 UpdateAfterChange(false, true); | |
| 539 OnAfterUserAction(); | |
| 540 return true; | |
| 541 } | |
| 542 | |
| 543 void Textfield::OnMouseReleased(const ui::MouseEvent& event) { | |
| 544 OnBeforeUserAction(); | |
| 545 // Cancel suspected drag initiations, the user was clicking in the selection. | |
| 546 if (initiating_drag_) | |
| 547 MoveCursorTo(event.location(), false); | |
| 548 initiating_drag_ = false; | |
| 549 UpdateSelectionClipboard(); | |
| 550 OnAfterUserAction(); | |
| 551 } | |
| 552 | |
| 553 void Textfield::OnFocus() { | |
| 554 GetRenderText()->set_focused(true); | |
| 555 cursor_visible_ = true; | |
| 556 SchedulePaint(); | |
| 557 GetInputMethod()->OnFocus(); | |
| 558 OnCaretBoundsChanged(); | |
| 559 | |
| 560 const size_t caret_blink_ms = Textfield::GetCaretBlinkMs(); | |
| 561 if (caret_blink_ms != 0) { | |
| 562 cursor_repaint_timer_.Start(FROM_HERE, | |
| 563 base::TimeDelta::FromMilliseconds(caret_blink_ms), this, | |
| 564 &Textfield::UpdateCursor); | |
| 565 } | |
| 566 | |
| 567 View::OnFocus(); | |
| 568 SchedulePaint(); | |
| 569 } | |
| 570 | |
| 571 void Textfield::OnBlur() { | |
| 572 GetRenderText()->set_focused(false); | |
| 573 GetInputMethod()->OnBlur(); | |
| 574 cursor_repaint_timer_.Stop(); | |
| 575 if (cursor_visible_) { | |
| 576 cursor_visible_ = false; | |
| 577 RepaintCursor(); | |
| 578 } | |
| 579 | |
| 580 touch_selection_controller_.reset(); | |
| 581 | |
| 582 // Border typically draws focus indicator. | |
| 583 SchedulePaint(); | |
| 584 } | |
| 585 | |
| 586 void Textfield::GetAccessibleState(ui::AXViewState* state) { | |
| 587 state->role = ui::AX_ROLE_TEXT_FIELD; | |
| 588 state->name = accessible_name_; | |
| 589 if (read_only()) | |
| 590 state->state |= ui::AX_STATE_READ_ONLY; | |
| 591 if (text_input_type_ == ui::TEXT_INPUT_TYPE_PASSWORD) | |
| 592 state->state |= ui::AX_STATE_PROTECTED; | |
| 593 state->value = text(); | |
| 594 | |
| 595 const gfx::Range range = GetSelectedRange(); | |
| 596 state->selection_start = range.start(); | |
| 597 state->selection_end = range.end(); | |
| 598 | |
| 599 if (!read_only()) { | |
| 600 state->set_value_callback = | |
| 601 base::Bind(&Textfield::AccessibilitySetValue, | |
| 602 weak_ptr_factory_.GetWeakPtr()); | |
| 603 } | |
| 604 } | |
| 605 | |
| 606 ui::TextInputClient* Textfield::GetTextInputClient() { | 546 ui::TextInputClient* Textfield::GetTextInputClient() { |
| 607 return read_only_ ? NULL : this; | 547 return read_only_ ? NULL : this; |
| 608 } | 548 } |
| 609 | 549 |
| 610 gfx::Point Textfield::GetKeyboardContextMenuLocation() { | |
| 611 return GetCaretBounds().bottom_right(); | |
| 612 } | |
| 613 | |
| 614 void Textfield::OnNativeThemeChanged(const ui::NativeTheme* theme) { | |
| 615 UpdateColorsFromTheme(theme); | |
| 616 } | |
| 617 | |
| 618 void Textfield::OnEnabledChanged() { | |
| 619 View::OnEnabledChanged(); | |
| 620 if (GetInputMethod()) | |
| 621 GetInputMethod()->OnTextInputTypeChanged(this); | |
| 622 SchedulePaint(); | |
| 623 } | |
| 624 | |
| 625 const char* Textfield::GetClassName() const { | |
| 626 return kViewClassName; | |
| 627 } | |
| 628 | |
| 629 gfx::NativeCursor Textfield::GetCursor(const ui::MouseEvent& event) { | |
| 630 bool in_selection = GetRenderText()->IsPointInSelection(event.location()); | |
| 631 bool drag_event = event.type() == ui::ET_MOUSE_DRAGGED; | |
| 632 bool text_cursor = !initiating_drag_ && (drag_event || !in_selection); | |
| 633 return text_cursor ? ui::kCursorIBeam : ui::kCursorNull; | |
| 634 } | |
| 635 | |
| 636 void Textfield::OnGestureEvent(ui::GestureEvent* event) { | 550 void Textfield::OnGestureEvent(ui::GestureEvent* event) { |
| 637 switch (event->type()) { | 551 switch (event->type()) { |
| 638 case ui::ET_GESTURE_TAP_DOWN: | 552 case ui::ET_GESTURE_TAP_DOWN: |
| 639 OnBeforeUserAction(); | 553 OnBeforeUserAction(); |
| 640 RequestFocus(); | 554 RequestFocus(); |
| 641 ShowImeIfNeeded(); | 555 ShowImeIfNeeded(); |
| 642 | 556 |
| 643 // We don't deselect if the point is in the selection | 557 // We don't deselect if the point is in the selection |
| 644 // because TAP_DOWN may turn into a LONG_PRESS. | 558 // because TAP_DOWN may turn into a LONG_PRESS. |
| 645 if (!GetRenderText()->IsPointInSelection(event->location())) | 559 if (!GetRenderText()->IsPointInSelection(event->location())) |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 // shown by the |touch_selection_controller_|, hence we mark the event | 621 // shown by the |touch_selection_controller_|, hence we mark the event |
| 708 // handled so views does not try to show context menu on it. | 622 // handled so views does not try to show context menu on it. |
| 709 if (touch_selection_controller_) | 623 if (touch_selection_controller_) |
| 710 event->SetHandled(); | 624 event->SetHandled(); |
| 711 break; | 625 break; |
| 712 default: | 626 default: |
| 713 return; | 627 return; |
| 714 } | 628 } |
| 715 } | 629 } |
| 716 | 630 |
| 631 void Textfield::AboutToRequestFocusFromTabTraversal(bool reverse) { |
| 632 SelectAll(false); |
| 633 } |
| 634 |
| 635 bool Textfield::SkipDefaultKeyEventProcessing(const ui::KeyEvent& e) { |
| 636 // Skip any accelerator handling of backspace; textfields handle this key. |
| 637 // Also skip processing Windows [Alt]+<num-pad digit> Unicode alt-codes. |
| 638 return e.key_code() == ui::VKEY_BACK || e.IsUnicodeKeyCode(); |
| 639 } |
| 640 |
| 717 bool Textfield::GetDropFormats( | 641 bool Textfield::GetDropFormats( |
| 718 int* formats, | 642 int* formats, |
| 719 std::set<OSExchangeData::CustomFormat>* custom_formats) { | 643 std::set<OSExchangeData::CustomFormat>* custom_formats) { |
| 720 if (!enabled() || read_only()) | 644 if (!enabled() || read_only()) |
| 721 return false; | 645 return false; |
| 722 // TODO(msw): Can we support URL, FILENAME, etc.? | 646 // TODO(msw): Can we support URL, FILENAME, etc.? |
| 723 *formats = ui::OSExchangeData::STRING; | 647 *formats = ui::OSExchangeData::STRING; |
| 724 if (controller_) | 648 if (controller_) |
| 725 controller_->AppendDropFormats(formats, custom_formats); | 649 controller_->AppendDropFormats(formats, custom_formats); |
| 726 return true; | 650 return true; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 UpdateAfterChange(true, true); | 722 UpdateAfterChange(true, true); |
| 799 OnAfterUserAction(); | 723 OnAfterUserAction(); |
| 800 return move ? ui::DragDropTypes::DRAG_MOVE : ui::DragDropTypes::DRAG_COPY; | 724 return move ? ui::DragDropTypes::DRAG_MOVE : ui::DragDropTypes::DRAG_COPY; |
| 801 } | 725 } |
| 802 | 726 |
| 803 void Textfield::OnDragDone() { | 727 void Textfield::OnDragDone() { |
| 804 initiating_drag_ = false; | 728 initiating_drag_ = false; |
| 805 drop_cursor_visible_ = false; | 729 drop_cursor_visible_ = false; |
| 806 } | 730 } |
| 807 | 731 |
| 732 void Textfield::GetAccessibleState(ui::AXViewState* state) { |
| 733 state->role = ui::AX_ROLE_TEXT_FIELD; |
| 734 state->name = accessible_name_; |
| 735 if (read_only()) |
| 736 state->state |= ui::AX_STATE_READ_ONLY; |
| 737 if (text_input_type_ == ui::TEXT_INPUT_TYPE_PASSWORD) |
| 738 state->state |= ui::AX_STATE_PROTECTED; |
| 739 state->value = text(); |
| 740 |
| 741 const gfx::Range range = GetSelectedRange(); |
| 742 state->selection_start = range.start(); |
| 743 state->selection_end = range.end(); |
| 744 |
| 745 if (!read_only()) { |
| 746 state->set_value_callback = |
| 747 base::Bind(&Textfield::AccessibilitySetValue, |
| 748 weak_ptr_factory_.GetWeakPtr()); |
| 749 } |
| 750 } |
| 751 |
| 808 void Textfield::OnBoundsChanged(const gfx::Rect& previous_bounds) { | 752 void Textfield::OnBoundsChanged(const gfx::Rect& previous_bounds) { |
| 809 GetRenderText()->SetDisplayRect(GetContentsBounds()); | 753 GetRenderText()->SetDisplayRect(GetContentsBounds()); |
| 810 OnCaretBoundsChanged(); | 754 OnCaretBoundsChanged(); |
| 811 } | 755 } |
| 812 | 756 |
| 757 void Textfield::OnEnabledChanged() { |
| 758 View::OnEnabledChanged(); |
| 759 if (GetInputMethod()) |
| 760 GetInputMethod()->OnTextInputTypeChanged(this); |
| 761 SchedulePaint(); |
| 762 } |
| 763 |
| 813 void Textfield::ViewHierarchyChanged( | 764 void Textfield::ViewHierarchyChanged( |
| 814 const ViewHierarchyChangedDetails& details) { | 765 const ViewHierarchyChangedDetails& details) { |
| 815 if (details.is_add && details.child == this) | 766 if (details.is_add && details.child == this) |
| 816 UpdateColorsFromTheme(GetNativeTheme()); | 767 UpdateColorsFromTheme(GetNativeTheme()); |
| 817 } | 768 } |
| 818 | 769 |
| 770 void Textfield::OnPaint(gfx::Canvas* canvas) { |
| 771 OnPaintBackground(canvas); |
| 772 PaintTextAndCursor(canvas); |
| 773 OnPaintBorder(canvas); |
| 774 if (NativeViewHost::kRenderNativeControlFocus) |
| 775 Painter::PaintFocusPainter(this, canvas, focus_painter_.get()); |
| 776 } |
| 777 |
| 778 void Textfield::OnFocus() { |
| 779 GetRenderText()->set_focused(true); |
| 780 cursor_visible_ = true; |
| 781 SchedulePaint(); |
| 782 GetInputMethod()->OnFocus(); |
| 783 OnCaretBoundsChanged(); |
| 784 |
| 785 const size_t caret_blink_ms = Textfield::GetCaretBlinkMs(); |
| 786 if (caret_blink_ms != 0) { |
| 787 cursor_repaint_timer_.Start(FROM_HERE, |
| 788 base::TimeDelta::FromMilliseconds(caret_blink_ms), this, |
| 789 &Textfield::UpdateCursor); |
| 790 } |
| 791 |
| 792 View::OnFocus(); |
| 793 SchedulePaint(); |
| 794 } |
| 795 |
| 796 void Textfield::OnBlur() { |
| 797 GetRenderText()->set_focused(false); |
| 798 GetInputMethod()->OnBlur(); |
| 799 cursor_repaint_timer_.Stop(); |
| 800 if (cursor_visible_) { |
| 801 cursor_visible_ = false; |
| 802 RepaintCursor(); |
| 803 } |
| 804 |
| 805 touch_selection_controller_.reset(); |
| 806 |
| 807 // Border typically draws focus indicator. |
| 808 SchedulePaint(); |
| 809 } |
| 810 |
| 811 gfx::Point Textfield::GetKeyboardContextMenuLocation() { |
| 812 return GetCaretBounds().bottom_right(); |
| 813 } |
| 814 |
| 815 void Textfield::OnNativeThemeChanged(const ui::NativeTheme* theme) { |
| 816 UpdateColorsFromTheme(theme); |
| 817 } |
| 818 |
| 819 //////////////////////////////////////////////////////////////////////////////// | 819 //////////////////////////////////////////////////////////////////////////////// |
| 820 // Textfield, TextfieldModel::Delegate overrides: | 820 // Textfield, TextfieldModel::Delegate overrides: |
| 821 | 821 |
| 822 void Textfield::OnCompositionTextConfirmedOrCleared() { | 822 void Textfield::OnCompositionTextConfirmedOrCleared() { |
| 823 if (!skip_input_method_cancel_composition_) | 823 if (!skip_input_method_cancel_composition_) |
| 824 GetInputMethod()->CancelComposition(this); | 824 GetInputMethod()->CancelComposition(this); |
| 825 } | 825 } |
| 826 | 826 |
| 827 //////////////////////////////////////////////////////////////////////////////// | 827 //////////////////////////////////////////////////////////////////////////////// |
| 828 // Textfield, ContextMenuController overrides: | 828 // Textfield, ContextMenuController overrides: |
| (...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1486 const size_t length = selection_clipboard_text.length(); | 1486 const size_t length = selection_clipboard_text.length(); |
| 1487 range = gfx::Range(range.start() + length, range.end() + length); | 1487 range = gfx::Range(range.start() + length, range.end() + length); |
| 1488 } | 1488 } |
| 1489 model_->MoveCursorTo(gfx::SelectionModel(range, affinity)); | 1489 model_->MoveCursorTo(gfx::SelectionModel(range, affinity)); |
| 1490 UpdateAfterChange(true, true); | 1490 UpdateAfterChange(true, true); |
| 1491 OnAfterUserAction(); | 1491 OnAfterUserAction(); |
| 1492 } | 1492 } |
| 1493 } | 1493 } |
| 1494 | 1494 |
| 1495 } // namespace views | 1495 } // namespace views |
| OLD | NEW |