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

Side by Side Diff: ui/views/controls/label_unittest.cc

Issue 2541313002: RenderTextHarfBuzz: Add support for multi line text selection. (Closed)
Patch Set: Fix test. Created 3 years, 12 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
« no previous file with comments | « ui/views/controls/label.cc ('k') | ui/views/controls/textfield/textfield_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/label.h" 5 #include "ui/views/controls/label.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/i18n/rtl.h" 10 #include "base/i18n/rtl.h"
(...skipping 10 matching lines...) Expand all
21 #include "ui/gfx/canvas.h" 21 #include "ui/gfx/canvas.h"
22 #include "ui/gfx/render_text.h" 22 #include "ui/gfx/render_text.h"
23 #include "ui/gfx/switches.h" 23 #include "ui/gfx/switches.h"
24 #include "ui/strings/grit/ui_strings.h" 24 #include "ui/strings/grit/ui_strings.h"
25 #include "ui/views/border.h" 25 #include "ui/views/border.h"
26 #include "ui/views/test/focus_manager_test.h" 26 #include "ui/views/test/focus_manager_test.h"
27 #include "ui/views/test/views_test_base.h" 27 #include "ui/views/test/views_test_base.h"
28 #include "ui/views/widget/widget.h" 28 #include "ui/views/widget/widget.h"
29 29
30 using base::ASCIIToUTF16; 30 using base::ASCIIToUTF16;
31 using base::WideToUTF16;
31 32
32 #define EXPECT_STR_EQ(ascii, utf16) EXPECT_EQ(ASCIIToUTF16(ascii), utf16) 33 #define EXPECT_STR_EQ(ascii, utf16) EXPECT_EQ(ASCIIToUTF16(ascii), utf16)
33 34
34 namespace views { 35 namespace views {
35 36
36 namespace { 37 namespace {
37 38
38 #if defined(OS_MACOSX) 39 #if defined(OS_MACOSX)
39 const int kControlCommandModifier = ui::EF_COMMAND_DOWN; 40 const int kControlCommandModifier = ui::EF_COMMAND_DOWN;
40 #else 41 #else
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 PerformMousePress(point, extra_flags); 173 PerformMousePress(point, extra_flags);
173 PerformMouseRelease(point); 174 PerformMouseRelease(point);
174 } 175 }
175 176
176 void PerformMouseDragTo(const gfx::Point& point) { 177 void PerformMouseDragTo(const gfx::Point& point) {
177 ui::MouseEvent drag(ui::ET_MOUSE_DRAGGED, point, point, 178 ui::MouseEvent drag(ui::ET_MOUSE_DRAGGED, point, point,
178 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0); 179 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0);
179 label()->OnMouseDragged(drag); 180 label()->OnMouseDragged(drag);
180 } 181 }
181 182
182 gfx::Point GetCursorPoint(int cursor_pos) { 183 // Used to force layout on the underlying RenderText instance.
183 return label() 184 void SimulatePaint() {
184 ->GetRenderTextForSelectionController() 185 gfx::Canvas canvas;
185 ->GetCursorBounds(gfx::SelectionModel(cursor_pos, gfx::CURSOR_FORWARD), 186 label()->OnPaint(&canvas);
186 false) 187 }
187 .origin(); 188
189 gfx::Point GetCursorPoint(int index) {
190 SimulatePaint();
191 gfx::RenderText* render_text =
192 label()->GetRenderTextForSelectionController();
193 const std::vector<gfx::Rect> bounds =
194 render_text->GetSubstringBoundsForTesting(gfx::Range(index, index + 1));
195 DCHECK_EQ(1u, bounds.size());
196
197 const bool rtl =
198 render_text->GetDisplayTextDirection() == base::i18n::RIGHT_TO_LEFT;
199 // Return Point corresponding to the leading edge of the character.
200 return gfx::Point(rtl ? bounds[0].right() - 1 : bounds[0].x() + 1,
201 bounds[0].y() + bounds[0].height() / 2);
202 }
203
204 size_t GetLineCount() {
205 SimulatePaint();
206 return label()->GetRenderTextForSelectionController()->GetNumLines();
188 } 207 }
189 208
190 base::string16 GetSelectedText() { return label()->GetSelectedText(); } 209 base::string16 GetSelectedText() { return label()->GetSelectedText(); }
191 210
192 ui::test::EventGenerator* event_generator() { return event_generator_.get(); } 211 ui::test::EventGenerator* event_generator() { return event_generator_.get(); }
193 212
194 bool IsMenuCommandEnabled(int command_id) { 213 bool IsMenuCommandEnabled(int command_id) {
195 return label()->IsCommandIdEnabled(command_id); 214 return label()->IsCommandIdEnabled(command_id);
196 } 215 }
197 216
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 EXPECT_LT(label()->font_list().GetHeight(), focus_bounds.height()); 832 EXPECT_LT(label()->font_list().GetHeight(), focus_bounds.height());
814 } 833 }
815 834
816 TEST_F(LabelSelectionTest, Selectable) { 835 TEST_F(LabelSelectionTest, Selectable) {
817 // By default, labels don't support text selection. 836 // By default, labels don't support text selection.
818 EXPECT_FALSE(label()->selectable()); 837 EXPECT_FALSE(label()->selectable());
819 838
820 ASSERT_TRUE(label()->SetSelectable(true)); 839 ASSERT_TRUE(label()->SetSelectable(true));
821 EXPECT_TRUE(label()->selectable()); 840 EXPECT_TRUE(label()->selectable());
822 841
823 // Verify that making a label multiline causes the label to not support text 842 // Verify that making a label multiline still causes the label to support text
824 // selection. 843 // selection.
825 label()->SetMultiLine(true); 844 label()->SetMultiLine(true);
826 EXPECT_FALSE(label()->selectable());
827
828 label()->SetMultiLine(false);
829 ASSERT_TRUE(label()->SetSelectable(true));
830 EXPECT_TRUE(label()->selectable()); 845 EXPECT_TRUE(label()->selectable());
831 846
832 // Verify that obscuring the label text causes the label to not support text 847 // Verify that obscuring the label text causes the label to not support text
833 // selection. 848 // selection.
834 label()->SetObscured(true); 849 label()->SetObscured(true);
835 EXPECT_FALSE(label()->selectable()); 850 EXPECT_FALSE(label()->selectable());
836 } 851 }
837 852
838 // Verify that labels supporting text selection get focus on clicks. 853 // Verify that labels supporting text selection get focus on clicks.
839 TEST_F(LabelSelectionTest, FocusOnClick) { 854 TEST_F(LabelSelectionTest, FocusOnClick) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 widget()->GetFocusManager()->AdvanceFocus(false); 894 widget()->GetFocusManager()->AdvanceFocus(false);
880 EXPECT_EQ(label(), GetFocusedView()); 895 EXPECT_EQ(label(), GetFocusedView());
881 } 896 }
882 897
883 // Verify label text selection behavior on double and triple clicks. 898 // Verify label text selection behavior on double and triple clicks.
884 TEST_F(LabelSelectionTest, DoubleTripleClick) { 899 TEST_F(LabelSelectionTest, DoubleTripleClick) {
885 label()->SetText(ASCIIToUTF16("Label double click")); 900 label()->SetText(ASCIIToUTF16("Label double click"));
886 label()->SizeToPreferredSize(); 901 label()->SizeToPreferredSize();
887 ASSERT_TRUE(label()->SetSelectable(true)); 902 ASSERT_TRUE(label()->SetSelectable(true));
888 903
889 PerformClick(gfx::Point()); 904 PerformClick(GetCursorPoint(0));
890 EXPECT_TRUE(GetSelectedText().empty()); 905 EXPECT_TRUE(GetSelectedText().empty());
891 906
892 // Double clicking should select the word under cursor. 907 // Double clicking should select the word under cursor.
893 PerformClick(gfx::Point(), ui::EF_IS_DOUBLE_CLICK); 908 PerformClick(GetCursorPoint(0), ui::EF_IS_DOUBLE_CLICK);
894 EXPECT_STR_EQ("Label", GetSelectedText()); 909 EXPECT_STR_EQ("Label", GetSelectedText());
895 910
896 // Triple clicking should select all the text. 911 // Triple clicking should select all the text.
897 PerformClick(gfx::Point()); 912 PerformClick(GetCursorPoint(0));
898 EXPECT_EQ(label()->text(), GetSelectedText()); 913 EXPECT_EQ(label()->text(), GetSelectedText());
899 914
900 // Clicking again should alternate to double click. 915 // Clicking again should alternate to double click.
901 PerformClick(gfx::Point()); 916 PerformClick(GetCursorPoint(0));
902 EXPECT_STR_EQ("Label", GetSelectedText()); 917 EXPECT_STR_EQ("Label", GetSelectedText());
903 918
904 // Clicking at another location should clear the selection. 919 // Clicking at another location should clear the selection.
905 PerformClick(GetCursorPoint(8)); 920 PerformClick(GetCursorPoint(8));
906 EXPECT_TRUE(GetSelectedText().empty()); 921 EXPECT_TRUE(GetSelectedText().empty());
907 PerformClick(GetCursorPoint(8), ui::EF_IS_DOUBLE_CLICK); 922 PerformClick(GetCursorPoint(8), ui::EF_IS_DOUBLE_CLICK);
908 EXPECT_STR_EQ("double", GetSelectedText()); 923 EXPECT_STR_EQ("double", GetSelectedText());
909 } 924 }
910 925
911 // Verify label text selection behavior on mouse drag. 926 // Verify label text selection behavior on mouse drag.
912 TEST_F(LabelSelectionTest, MouseDrag) { 927 TEST_F(LabelSelectionTest, MouseDrag) {
913 label()->SetText(ASCIIToUTF16("Label mouse drag")); 928 label()->SetText(ASCIIToUTF16("Label mouse drag"));
914 label()->SizeToPreferredSize(); 929 label()->SizeToPreferredSize();
915 ASSERT_TRUE(label()->SetSelectable(true)); 930 ASSERT_TRUE(label()->SetSelectable(true));
916 931
917 PerformMousePress(GetCursorPoint(5)); 932 PerformMousePress(GetCursorPoint(5));
918 PerformMouseDragTo(gfx::Point()); 933 PerformMouseDragTo(GetCursorPoint(0));
919 EXPECT_STR_EQ("Label", GetSelectedText()); 934 EXPECT_STR_EQ("Label", GetSelectedText());
920 935
921 PerformMouseDragTo(GetCursorPoint(8)); 936 PerformMouseDragTo(GetCursorPoint(8));
922 EXPECT_STR_EQ(" mo", GetSelectedText()); 937 EXPECT_STR_EQ(" mo", GetSelectedText());
923 938
924 PerformMouseDragTo(gfx::Point(200, 0)); 939 PerformMouseDragTo(gfx::Point(200, GetCursorPoint(0).y()));
925 PerformMouseRelease(gfx::Point(200, 0)); 940 PerformMouseRelease(gfx::Point(200, GetCursorPoint(0).y()));
926 EXPECT_STR_EQ(" mouse drag", GetSelectedText()); 941 EXPECT_STR_EQ(" mouse drag", GetSelectedText());
927 942
928 event_generator()->PressKey(ui::VKEY_C, kControlCommandModifier); 943 event_generator()->PressKey(ui::VKEY_C, kControlCommandModifier);
929 EXPECT_STR_EQ(" mouse drag", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE)); 944 EXPECT_STR_EQ(" mouse drag", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
930 } 945 }
931 946
947 TEST_F(LabelSelectionTest, MouseDragMultilineLTR) {
948 label()->SetMultiLine(true);
949 label()->SetText(ASCIIToUTF16("abcd\nefgh"));
950 label()->SizeToPreferredSize();
951 ASSERT_TRUE(label()->SetSelectable(true));
952 ASSERT_EQ(2u, GetLineCount());
953
954 PerformMousePress(GetCursorPoint(2));
955 PerformMouseDragTo(GetCursorPoint(0));
956 EXPECT_STR_EQ("ab", GetSelectedText());
957
958 PerformMouseDragTo(GetCursorPoint(7));
959 EXPECT_STR_EQ("cd\nef", GetSelectedText());
960
961 PerformMouseDragTo(gfx::Point(-5, GetCursorPoint(6).y()));
962 EXPECT_STR_EQ("cd\n", GetSelectedText());
963
964 PerformMouseDragTo(gfx::Point(100, GetCursorPoint(6).y()));
965 EXPECT_STR_EQ("cd\nefgh", GetSelectedText());
966
967 PerformMouseDragTo(gfx::Point(GetCursorPoint(3).x(), -5));
968 EXPECT_STR_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds ? "ab" : "c",
969 GetSelectedText());
970
971 PerformMouseDragTo(gfx::Point(GetCursorPoint(7).x(), 100));
972 EXPECT_STR_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds ? "cd\nefgh"
973 : "cd\nef",
974 GetSelectedText());
975 }
976
977 TEST_F(LabelSelectionTest, MouseDragMultilineRTL) {
978 label()->SetMultiLine(true);
979 label()->SetText(WideToUTF16(L"\x5d0\x5d1\x5d2\n\x5d3\x5d4\x5d5"));
980 label()->SizeToPreferredSize();
981 ASSERT_TRUE(label()->SetSelectable(true));
982 ASSERT_EQ(2u, GetLineCount());
983
984 PerformMousePress(GetCursorPoint(1));
985 PerformMouseDragTo(GetCursorPoint(0));
986 EXPECT_EQ(WideToUTF16(L"\x5d0"), GetSelectedText());
987
988 PerformMouseDragTo(GetCursorPoint(6));
989 EXPECT_EQ(WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4"), GetSelectedText());
990
991 PerformMouseDragTo(gfx::Point(-5, GetCursorPoint(6).y()));
992 EXPECT_EQ(WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4\x5d5"), GetSelectedText());
993
994 PerformMouseDragTo(gfx::Point(100, GetCursorPoint(6).y()));
995 EXPECT_EQ(WideToUTF16(L"\x5d1\x5d2\n"), GetSelectedText());
996
997 PerformMouseDragTo(gfx::Point(GetCursorPoint(2).x(), -5));
998 EXPECT_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds
999 ? WideToUTF16(L"\x5d0")
1000 : WideToUTF16(L"\x5d1"),
1001 GetSelectedText());
1002
1003 PerformMouseDragTo(gfx::Point(GetCursorPoint(6).x(), 100));
1004 EXPECT_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds
1005 ? WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4\x5d5")
1006 : WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4"),
1007 GetSelectedText());
1008 }
1009
932 // Verify the initially selected word on a double click, remains selected on 1010 // Verify the initially selected word on a double click, remains selected on
933 // mouse dragging. 1011 // mouse dragging.
934 TEST_F(LabelSelectionTest, MouseDragWord) { 1012 TEST_F(LabelSelectionTest, MouseDragWord) {
935 label()->SetText(ASCIIToUTF16("Label drag word")); 1013 label()->SetText(ASCIIToUTF16("Label drag word"));
936 label()->SizeToPreferredSize(); 1014 label()->SizeToPreferredSize();
937 ASSERT_TRUE(label()->SetSelectable(true)); 1015 ASSERT_TRUE(label()->SetSelectable(true));
938 1016
939 PerformClick(GetCursorPoint(8)); 1017 PerformClick(GetCursorPoint(8));
940 PerformMousePress(GetCursorPoint(8), ui::EF_IS_DOUBLE_CLICK); 1018 PerformMousePress(GetCursorPoint(8), ui::EF_IS_DOUBLE_CLICK);
941 EXPECT_STR_EQ("drag", GetSelectedText()); 1019 EXPECT_STR_EQ("drag", GetSelectedText());
942 1020
943 PerformMouseDragTo(gfx::Point()); 1021 PerformMouseDragTo(GetCursorPoint(0));
944 EXPECT_STR_EQ("Label drag", GetSelectedText()); 1022 EXPECT_STR_EQ("Label drag", GetSelectedText());
945 1023
946 PerformMouseDragTo(gfx::Point(200, 0)); 1024 PerformMouseDragTo(gfx::Point(200, GetCursorPoint(0).y()));
947 PerformMouseRelease(gfx::Point(200, 0)); 1025 PerformMouseRelease(gfx::Point(200, GetCursorPoint(0).y()));
948 EXPECT_STR_EQ("drag word", GetSelectedText()); 1026 EXPECT_STR_EQ("drag word", GetSelectedText());
949 } 1027 }
950 1028
951 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 1029 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
952 // Verify selection clipboard behavior on text selection. 1030 // Verify selection clipboard behavior on text selection.
953 TEST_F(LabelSelectionTest, SelectionClipboard) { 1031 TEST_F(LabelSelectionTest, SelectionClipboard) {
954 label()->SetText(ASCIIToUTF16("Label selection clipboard")); 1032 label()->SetText(ASCIIToUTF16("Label selection clipboard"));
955 label()->SizeToPreferredSize(); 1033 label()->SizeToPreferredSize();
956 ASSERT_TRUE(label()->SetSelectable(true)); 1034 ASSERT_TRUE(label()->SetSelectable(true));
957 1035
958 // Verify programmatic modification of selection, does not modify the 1036 // Verify programmatic modification of selection, does not modify the
959 // selection clipboard. 1037 // selection clipboard.
960 label()->SelectRange(gfx::Range(2, 5)); 1038 label()->SelectRange(gfx::Range(2, 5));
961 EXPECT_STR_EQ("bel", GetSelectedText()); 1039 EXPECT_STR_EQ("bel", GetSelectedText());
962 EXPECT_TRUE(GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION).empty()); 1040 EXPECT_TRUE(GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION).empty());
963 1041
964 // Verify text selection using the mouse updates the selection clipboard. 1042 // Verify text selection using the mouse updates the selection clipboard.
965 PerformMousePress(GetCursorPoint(5)); 1043 PerformMousePress(GetCursorPoint(5));
966 PerformMouseDragTo(gfx::Point()); 1044 PerformMouseDragTo(GetCursorPoint(0));
967 PerformMouseRelease(gfx::Point()); 1045 PerformMouseRelease(GetCursorPoint(0));
968 EXPECT_STR_EQ("Label", GetSelectedText()); 1046 EXPECT_STR_EQ("Label", GetSelectedText());
969 EXPECT_STR_EQ("Label", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION)); 1047 EXPECT_STR_EQ("Label", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
970 } 1048 }
971 #endif 1049 #endif
972 1050
973 // Verify that keyboard shortcuts for Copy and Select All work when a selectable 1051 // Verify that keyboard shortcuts for Copy and Select All work when a selectable
974 // label is focused. 1052 // label is focused.
975 TEST_F(LabelSelectionTest, KeyboardActions) { 1053 TEST_F(LabelSelectionTest, KeyboardActions) {
976 const base::string16 initial_text = ASCIIToUTF16("Label keyboard actions"); 1054 const base::string16 initial_text = ASCIIToUTF16("Label keyboard actions");
977 label()->SetText(initial_text); 1055 label()->SetText(initial_text);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 label()->SetObscured(false); 1112 label()->SetObscured(false);
1035 1113
1036 // For an empty label, both COPY and SELECT_ALL should be disabled. 1114 // For an empty label, both COPY and SELECT_ALL should be disabled.
1037 label()->SetText(base::string16()); 1115 label()->SetText(base::string16());
1038 ASSERT_TRUE(label()->SetSelectable(true)); 1116 ASSERT_TRUE(label()->SetSelectable(true));
1039 EXPECT_FALSE(IsMenuCommandEnabled(IDS_APP_COPY)); 1117 EXPECT_FALSE(IsMenuCommandEnabled(IDS_APP_COPY));
1040 EXPECT_FALSE(IsMenuCommandEnabled(IDS_APP_SELECT_ALL)); 1118 EXPECT_FALSE(IsMenuCommandEnabled(IDS_APP_SELECT_ALL));
1041 } 1119 }
1042 1120
1043 } // namespace views 1121 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/label.cc ('k') | ui/views/controls/textfield/textfield_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698