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

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

Issue 1031533002: Supports the invisible underline for native input fields. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: revised per comments and fixed test failures. Created 5 years, 9 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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_model.h" 5 #include "ui/views/controls/textfield/textfield_model.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 CancelCompositionText(); 557 CancelCompositionText();
558 else if (HasSelection()) 558 else if (HasSelection())
559 DeleteSelection(); 559 DeleteSelection();
560 560
561 if (composition.text.empty()) 561 if (composition.text.empty())
562 return; 562 return;
563 563
564 size_t cursor = GetCursorPosition(); 564 size_t cursor = GetCursorPosition();
565 base::string16 new_text = text(); 565 base::string16 new_text = text();
566 render_text_->SetText(new_text.insert(cursor, composition.text)); 566 render_text_->SetText(new_text.insert(cursor, composition.text));
567 gfx::Range range(cursor, cursor + composition.text.length()); 567 composition_range_ = gfx::Range(cursor, cursor + composition.text.length());
568 render_text_->SetCompositionRange(range); 568 // Don't render the underline for composition which is configured as
msw 2015/03/26 20:22:48 nit: "Don't render transparent composition underli
Shu Chen 2015/03/30 03:56:21 Done.
569 // transparent color.
570 if (composition.underlines.size() > 0 && composition.underlines[0].color != 0)
571 render_text_->SetCompositionRange(composition_range_);
572 else
573 render_text_->SetCompositionRange(gfx::Range::InvalidRange());
569 gfx::Range emphasized_range = GetFirstEmphasizedRange(composition); 574 gfx::Range emphasized_range = GetFirstEmphasizedRange(composition);
570 if (emphasized_range.IsValid()) { 575 if (emphasized_range.IsValid()) {
571 // This is a workaround due to the lack of support in RenderText to draw 576 // This is a workaround due to the lack of support in RenderText to draw
572 // a thick underline. In a composition returned from an IME, the segment 577 // a thick underline. In a composition returned from an IME, the segment
573 // emphasized by a thick underline usually represents the target clause. 578 // emphasized by a thick underline usually represents the target clause.
574 // Because the target clause is more important than the actual selection 579 // Because the target clause is more important than the actual selection
575 // range (or caret position) in the composition here we use a selection-like 580 // range (or caret position) in the composition here we use a selection-like
576 // marker instead to show this range. 581 // marker instead to show this range.
577 // TODO(yukawa, msw): Support thick underlines and remove this workaround. 582 // TODO(yukawa, msw): Support thick underlines and remove this workaround.
578 render_text_->SelectRange(gfx::Range( 583 render_text_->SelectRange(gfx::Range(
579 cursor + emphasized_range.GetMin(), 584 cursor + emphasized_range.GetMin(),
580 cursor + emphasized_range.GetMax())); 585 cursor + emphasized_range.GetMax()));
581 } else if (!composition.selection.is_empty()) { 586 } else if (!composition.selection.is_empty()) {
582 render_text_->SelectRange(gfx::Range( 587 render_text_->SelectRange(gfx::Range(
583 cursor + composition.selection.GetMin(), 588 cursor + composition.selection.GetMin(),
584 cursor + composition.selection.GetMax())); 589 cursor + composition.selection.GetMax()));
585 } else { 590 } else {
586 render_text_->SetCursorPosition(cursor + composition.selection.end()); 591 render_text_->SetCursorPosition(cursor + composition.selection.end());
587 } 592 }
588 } 593 }
589 594
590 void TextfieldModel::ConfirmCompositionText() { 595 void TextfieldModel::ConfirmCompositionText() {
591 DCHECK(HasCompositionText()); 596 DCHECK(HasCompositionText());
592 gfx::Range range = render_text_->GetCompositionRange(); 597 base::string16 composition = text().substr(
593 base::string16 composition = text().substr(range.start(), range.length()); 598 composition_range_.start(), composition_range_.length());
594 // TODO(oshima): current behavior on ChromeOS is a bit weird and not 599 // TODO(oshima): current behavior on ChromeOS is a bit weird and not
595 // sure exactly how this should work. Find out and fix if necessary. 600 // sure exactly how this should work. Find out and fix if necessary.
596 AddOrMergeEditHistory(new InsertEdit(false, composition, range.start())); 601 AddOrMergeEditHistory(
597 render_text_->SetCursorPosition(range.end()); 602 new InsertEdit(false, composition, composition_range_.start()));
603 render_text_->SetCursorPosition(composition_range_.end());
598 ClearComposition(); 604 ClearComposition();
599 if (delegate_) 605 if (delegate_)
600 delegate_->OnCompositionTextConfirmedOrCleared(); 606 delegate_->OnCompositionTextConfirmedOrCleared();
601 } 607 }
602 608
603 void TextfieldModel::CancelCompositionText() { 609 void TextfieldModel::CancelCompositionText() {
604 DCHECK(HasCompositionText()); 610 DCHECK(HasCompositionText());
605 gfx::Range range = render_text_->GetCompositionRange(); 611 gfx::Range range = composition_range_;
606 ClearComposition(); 612 ClearComposition();
607 base::string16 new_text = text(); 613 base::string16 new_text = text();
608 render_text_->SetText(new_text.erase(range.start(), range.length())); 614 render_text_->SetText(new_text.erase(range.start(), range.length()));
609 render_text_->SetCursorPosition(range.start()); 615 render_text_->SetCursorPosition(range.start());
610 if (delegate_) 616 if (delegate_)
611 delegate_->OnCompositionTextConfirmedOrCleared(); 617 delegate_->OnCompositionTextConfirmedOrCleared();
612 } 618 }
613 619
614 void TextfieldModel::ClearComposition() { 620 void TextfieldModel::ClearComposition() {
615 render_text_->SetCompositionRange(gfx::Range::InvalidRange()); 621 composition_range_ = gfx::Range::InvalidRange();
622 render_text_->SetCompositionRange(composition_range_);
616 } 623 }
617 624
618 void TextfieldModel::GetCompositionTextRange(gfx::Range* range) const { 625 void TextfieldModel::GetCompositionTextRange(gfx::Range* range) const {
619 *range = gfx::Range(render_text_->GetCompositionRange()); 626 *range = composition_range_;
620 } 627 }
621 628
622 bool TextfieldModel::HasCompositionText() const { 629 bool TextfieldModel::HasCompositionText() const {
623 return !render_text_->GetCompositionRange().is_empty(); 630 return !composition_range_.is_empty();
624 } 631 }
625 632
626 void TextfieldModel::ClearEditHistory() { 633 void TextfieldModel::ClearEditHistory() {
627 STLDeleteElements(&edit_history_); 634 STLDeleteElements(&edit_history_);
628 current_edit_ = edit_history_.end(); 635 current_edit_ = edit_history_.end();
629 } 636 }
630 637
631 ///////////////////////////////////////////////////////////////// 638 /////////////////////////////////////////////////////////////////
632 // TextfieldModel: private 639 // TextfieldModel: private
633 640
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 ClearComposition(); 767 ClearComposition();
761 if (delete_from != delete_to) 768 if (delete_from != delete_to)
762 render_text_->SetText(old_text.erase(delete_from, delete_to - delete_from)); 769 render_text_->SetText(old_text.erase(delete_from, delete_to - delete_from));
763 if (!new_text.empty()) 770 if (!new_text.empty())
764 render_text_->SetText(old_text.insert(new_text_insert_at, new_text)); 771 render_text_->SetText(old_text.insert(new_text_insert_at, new_text));
765 render_text_->SetCursorPosition(new_cursor_pos); 772 render_text_->SetCursorPosition(new_cursor_pos);
766 // TODO(oshima): Select text that was just undone, like Mac (but not GTK). 773 // TODO(oshima): Select text that was just undone, like Mac (but not GTK).
767 } 774 }
768 775
769 } // namespace views 776 } // namespace views
OLDNEW
« ui/base/ime/composition_text.cc ('K') | « ui/views/controls/textfield/textfield_model.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698