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

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

Issue 2541313002: RenderTextHarfBuzz: Add support for multi line text selection. (Closed)
Patch Set: Tests Created 4 years 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 (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 gfx::Point GetCursorPoint(int index, bool rtl = false) {
msw 2016/12/13 03:04:56 nit: can we check if the text is rtl instead of pa
karandeepb 2016/12/16 02:58:38 Done.
183 return label() 184 label()->GetRenderTextForSelectionController()->EnsureLayout();
184 ->GetRenderTextForSelectionController() 185 const std::vector<gfx::Rect> bounds =
185 ->GetCursorBounds(gfx::SelectionModel(cursor_pos, gfx::CURSOR_FORWARD), 186 label()->GetRenderTextForSelectionController()->GetSubstringBounds(
186 false) 187 gfx::Range(index, index + 1));
187 .origin(); 188 DCHECK_EQ(1u, bounds.size());
189 // Return Point corresponding to the leading edge of the character.
190 return gfx::Point(rtl ? bounds[0].right() - 1 : bounds[0].x() + 1,
191 bounds[0].y() + bounds[0].height() / 2);
192 }
193
194 size_t GetLineCount() {
195 label()->GetRenderTextForSelectionController()->EnsureLayout();
196 return label()->GetRenderTextForSelectionController()->lines().size();
188 } 197 }
189 198
190 base::string16 GetSelectedText() { return label()->GetSelectedText(); } 199 base::string16 GetSelectedText() { return label()->GetSelectedText(); }
191 200
192 ui::test::EventGenerator* event_generator() { return event_generator_.get(); } 201 ui::test::EventGenerator* event_generator() { return event_generator_.get(); }
193 202
194 bool IsMenuCommandEnabled(int command_id) { 203 bool IsMenuCommandEnabled(int command_id) {
195 return label()->IsCommandIdEnabled(command_id); 204 return label()->IsCommandIdEnabled(command_id);
196 } 205 }
197 206
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 EXPECT_LT(label()->font_list().GetHeight(), focus_bounds.height()); 822 EXPECT_LT(label()->font_list().GetHeight(), focus_bounds.height());
814 } 823 }
815 824
816 TEST_F(LabelSelectionTest, Selectable) { 825 TEST_F(LabelSelectionTest, Selectable) {
817 // By default, labels don't support text selection. 826 // By default, labels don't support text selection.
818 EXPECT_FALSE(label()->selectable()); 827 EXPECT_FALSE(label()->selectable());
819 828
820 ASSERT_TRUE(label()->SetSelectable(true)); 829 ASSERT_TRUE(label()->SetSelectable(true));
821 EXPECT_TRUE(label()->selectable()); 830 EXPECT_TRUE(label()->selectable());
822 831
823 // Verify that making a label multiline causes the label to not support text 832 // Verify that making a label multiline still causes the label to support text
824 // selection. 833 // selection.
825 label()->SetMultiLine(true); 834 label()->SetMultiLine(true);
826 EXPECT_FALSE(label()->selectable());
827
828 label()->SetMultiLine(false);
829 ASSERT_TRUE(label()->SetSelectable(true));
830 EXPECT_TRUE(label()->selectable()); 835 EXPECT_TRUE(label()->selectable());
831 836
832 // Verify that obscuring the label text causes the label to not support text 837 // Verify that obscuring the label text causes the label to not support text
833 // selection. 838 // selection.
834 label()->SetObscured(true); 839 label()->SetObscured(true);
835 EXPECT_FALSE(label()->selectable()); 840 EXPECT_FALSE(label()->selectable());
836 } 841 }
837 842
838 // Verify that labels supporting text selection get focus on clicks. 843 // Verify that labels supporting text selection get focus on clicks.
839 TEST_F(LabelSelectionTest, FocusOnClick) { 844 TEST_F(LabelSelectionTest, FocusOnClick) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 widget()->GetFocusManager()->AdvanceFocus(false); 884 widget()->GetFocusManager()->AdvanceFocus(false);
880 EXPECT_EQ(label(), GetFocusedView()); 885 EXPECT_EQ(label(), GetFocusedView());
881 } 886 }
882 887
883 // Verify label text selection behavior on double and triple clicks. 888 // Verify label text selection behavior on double and triple clicks.
884 TEST_F(LabelSelectionTest, DoubleTripleClick) { 889 TEST_F(LabelSelectionTest, DoubleTripleClick) {
885 label()->SetText(ASCIIToUTF16("Label double click")); 890 label()->SetText(ASCIIToUTF16("Label double click"));
886 label()->SizeToPreferredSize(); 891 label()->SizeToPreferredSize();
887 ASSERT_TRUE(label()->SetSelectable(true)); 892 ASSERT_TRUE(label()->SetSelectable(true));
888 893
889 PerformClick(gfx::Point()); 894 PerformClick(GetCursorPoint(0));
890 EXPECT_TRUE(GetSelectedText().empty()); 895 EXPECT_TRUE(GetSelectedText().empty());
891 896
892 // Double clicking should select the word under cursor. 897 // Double clicking should select the word under cursor.
893 PerformClick(gfx::Point(), ui::EF_IS_DOUBLE_CLICK); 898 PerformClick(GetCursorPoint(0), ui::EF_IS_DOUBLE_CLICK);
894 EXPECT_STR_EQ("Label", GetSelectedText()); 899 EXPECT_STR_EQ("Label", GetSelectedText());
895 900
896 // Triple clicking should select all the text. 901 // Triple clicking should select all the text.
897 PerformClick(gfx::Point()); 902 PerformClick(GetCursorPoint(0));
898 EXPECT_EQ(label()->text(), GetSelectedText()); 903 EXPECT_EQ(label()->text(), GetSelectedText());
899 904
900 // Clicking again should alternate to double click. 905 // Clicking again should alternate to double click.
901 PerformClick(gfx::Point()); 906 PerformClick(GetCursorPoint(0));
902 EXPECT_STR_EQ("Label", GetSelectedText()); 907 EXPECT_STR_EQ("Label", GetSelectedText());
903 908
904 // Clicking at another location should clear the selection. 909 // Clicking at another location should clear the selection.
905 PerformClick(GetCursorPoint(8)); 910 PerformClick(GetCursorPoint(8));
906 EXPECT_TRUE(GetSelectedText().empty()); 911 EXPECT_TRUE(GetSelectedText().empty());
907 PerformClick(GetCursorPoint(8), ui::EF_IS_DOUBLE_CLICK); 912 PerformClick(GetCursorPoint(8), ui::EF_IS_DOUBLE_CLICK);
908 EXPECT_STR_EQ("double", GetSelectedText()); 913 EXPECT_STR_EQ("double", GetSelectedText());
909 } 914 }
910 915
911 // Verify label text selection behavior on mouse drag. 916 // Verify label text selection behavior on mouse drag.
912 TEST_F(LabelSelectionTest, MouseDrag) { 917 TEST_F(LabelSelectionTest, MouseDrag) {
913 label()->SetText(ASCIIToUTF16("Label mouse drag")); 918 label()->SetText(ASCIIToUTF16("Label mouse drag"));
914 label()->SizeToPreferredSize(); 919 label()->SizeToPreferredSize();
915 ASSERT_TRUE(label()->SetSelectable(true)); 920 ASSERT_TRUE(label()->SetSelectable(true));
916 921
917 PerformMousePress(GetCursorPoint(5)); 922 PerformMousePress(GetCursorPoint(5));
918 PerformMouseDragTo(gfx::Point()); 923 PerformMouseDragTo(GetCursorPoint(0));
919 EXPECT_STR_EQ("Label", GetSelectedText()); 924 EXPECT_STR_EQ("Label", GetSelectedText());
920 925
921 PerformMouseDragTo(GetCursorPoint(8)); 926 PerformMouseDragTo(GetCursorPoint(8));
922 EXPECT_STR_EQ(" mo", GetSelectedText()); 927 EXPECT_STR_EQ(" mo", GetSelectedText());
923 928
924 PerformMouseDragTo(gfx::Point(200, 0)); 929 PerformMouseDragTo(gfx::Point(200, GetCursorPoint(0).y()));
925 PerformMouseRelease(gfx::Point(200, 0)); 930 PerformMouseRelease(gfx::Point(200, GetCursorPoint(0).y()));
926 EXPECT_STR_EQ(" mouse drag", GetSelectedText()); 931 EXPECT_STR_EQ(" mouse drag", GetSelectedText());
927 932
928 event_generator()->PressKey(ui::VKEY_C, kControlCommandModifier); 933 event_generator()->PressKey(ui::VKEY_C, kControlCommandModifier);
929 EXPECT_STR_EQ(" mouse drag", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE)); 934 EXPECT_STR_EQ(" mouse drag", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
930 } 935 }
931 936
937 TEST_F(LabelSelectionTest, MouseDragMultilineLTR) {
938 label()->SetMultiLine(true);
939 label()->SetText(ASCIIToUTF16("abcd\nefgh"));
940 label()->SizeToPreferredSize();
941 ASSERT_TRUE(label()->SetSelectable(true));
942 ASSERT_EQ(2u, GetLineCount());
943
944 PerformMousePress(GetCursorPoint(2));
945 PerformMouseDragTo(GetCursorPoint(0));
946 EXPECT_STR_EQ("ab", GetSelectedText());
947
948 PerformMouseDragTo(GetCursorPoint(7));
949 EXPECT_STR_EQ("cd\nef", GetSelectedText());
950
951 PerformMouseDragTo(gfx::Point(-5, GetCursorPoint(6).y()));
952 EXPECT_STR_EQ("cd\n", GetSelectedText());
953
954 PerformMouseDragTo(gfx::Point(100, GetCursorPoint(6).y()));
955 EXPECT_STR_EQ("cd\nefgh", GetSelectedText());
956
957 PerformMouseDragTo(gfx::Point(GetCursorPoint(3).x(), -5));
958 EXPECT_STR_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds ? "ab" : "c",
959 GetSelectedText());
960
961 PerformMouseDragTo(gfx::Point(GetCursorPoint(7).x(), 100));
962 EXPECT_STR_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds ? "cd\nefgh"
963 : "cd\nef",
964 GetSelectedText());
965 }
966
967 TEST_F(LabelSelectionTest, MouseDragMultilineRTL) {
968 label()->SetMultiLine(true);
969 label()->SetText(WideToUTF16(L"\x5d0\x5d1\x5d2\n\x5d3\x5d4\x5d5"));
970 label()->SizeToPreferredSize();
971 ASSERT_TRUE(label()->SetSelectable(true));
972 ASSERT_EQ(2u, GetLineCount());
973
974 PerformMousePress(GetCursorPoint(1, true));
975 PerformMouseDragTo(GetCursorPoint(0, true));
976 EXPECT_EQ(WideToUTF16(L"\x5d0"), GetSelectedText());
977
978 PerformMouseDragTo(GetCursorPoint(6, true));
979 EXPECT_EQ(WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4"), GetSelectedText());
980
981 PerformMouseDragTo(gfx::Point(-5, GetCursorPoint(6, true).y()));
982 EXPECT_EQ(WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4\x5d5"), GetSelectedText());
983
984 PerformMouseDragTo(gfx::Point(100, GetCursorPoint(6, true).y()));
985 EXPECT_EQ(WideToUTF16(L"\x5d1\x5d2\n"), GetSelectedText());
986
987 PerformMouseDragTo(gfx::Point(GetCursorPoint(2, true).x(), -5));
988 EXPECT_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds
989 ? WideToUTF16(L"\x5d0")
990 : WideToUTF16(L"\x5d1"),
991 GetSelectedText());
992
993 PerformMouseDragTo(gfx::Point(GetCursorPoint(6, true).x(), 100));
994 EXPECT_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds
995 ? WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4\x5d5")
996 : WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4"),
997 GetSelectedText());
998 }
999
932 // Verify the initially selected word on a double click, remains selected on 1000 // Verify the initially selected word on a double click, remains selected on
933 // mouse dragging. 1001 // mouse dragging.
934 TEST_F(LabelSelectionTest, MouseDragWord) { 1002 TEST_F(LabelSelectionTest, MouseDragWord) {
935 label()->SetText(ASCIIToUTF16("Label drag word")); 1003 label()->SetText(ASCIIToUTF16("Label drag word"));
936 label()->SizeToPreferredSize(); 1004 label()->SizeToPreferredSize();
937 ASSERT_TRUE(label()->SetSelectable(true)); 1005 ASSERT_TRUE(label()->SetSelectable(true));
938 1006
939 PerformClick(GetCursorPoint(8)); 1007 PerformClick(GetCursorPoint(8));
940 PerformMousePress(GetCursorPoint(8), ui::EF_IS_DOUBLE_CLICK); 1008 PerformMousePress(GetCursorPoint(8), ui::EF_IS_DOUBLE_CLICK);
941 EXPECT_STR_EQ("drag", GetSelectedText()); 1009 EXPECT_STR_EQ("drag", GetSelectedText());
942 1010
943 PerformMouseDragTo(gfx::Point()); 1011 PerformMouseDragTo(GetCursorPoint(0));
944 EXPECT_STR_EQ("Label drag", GetSelectedText()); 1012 EXPECT_STR_EQ("Label drag", GetSelectedText());
945 1013
946 PerformMouseDragTo(gfx::Point(200, 0)); 1014 PerformMouseDragTo(gfx::Point(200, GetCursorPoint(0).y()));
947 PerformMouseRelease(gfx::Point(200, 0)); 1015 PerformMouseRelease(gfx::Point(200, GetCursorPoint(0).y()));
948 EXPECT_STR_EQ("drag word", GetSelectedText()); 1016 EXPECT_STR_EQ("drag word", GetSelectedText());
949 } 1017 }
950 1018
951 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 1019 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
952 // Verify selection clipboard behavior on text selection. 1020 // Verify selection clipboard behavior on text selection.
953 TEST_F(LabelSelectionTest, SelectionClipboard) { 1021 TEST_F(LabelSelectionTest, SelectionClipboard) {
954 label()->SetText(ASCIIToUTF16("Label selection clipboard")); 1022 label()->SetText(ASCIIToUTF16("Label selection clipboard"));
955 label()->SizeToPreferredSize(); 1023 label()->SizeToPreferredSize();
956 ASSERT_TRUE(label()->SetSelectable(true)); 1024 ASSERT_TRUE(label()->SetSelectable(true));
957 1025
958 // Verify programmatic modification of selection, does not modify the 1026 // Verify programmatic modification of selection, does not modify the
959 // selection clipboard. 1027 // selection clipboard.
960 label()->SelectRange(gfx::Range(2, 5)); 1028 label()->SelectRange(gfx::Range(2, 5));
961 EXPECT_STR_EQ("bel", GetSelectedText()); 1029 EXPECT_STR_EQ("bel", GetSelectedText());
962 EXPECT_TRUE(GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION).empty()); 1030 EXPECT_TRUE(GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION).empty());
963 1031
964 // Verify text selection using the mouse updates the selection clipboard. 1032 // Verify text selection using the mouse updates the selection clipboard.
965 PerformMousePress(GetCursorPoint(5)); 1033 PerformMousePress(GetCursorPoint(5));
966 PerformMouseDragTo(gfx::Point()); 1034 PerformMouseDragTo(GetCursorPoint(0));
967 PerformMouseRelease(gfx::Point()); 1035 PerformMouseRelease(GetCursorPoint(0));
968 EXPECT_STR_EQ("Label", GetSelectedText()); 1036 EXPECT_STR_EQ("Label", GetSelectedText());
969 EXPECT_STR_EQ("Label", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION)); 1037 EXPECT_STR_EQ("Label", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
970 } 1038 }
971 #endif 1039 #endif
972 1040
973 // Verify that keyboard shortcuts for Copy and Select All work when a selectable 1041 // Verify that keyboard shortcuts for Copy and Select All work when a selectable
974 // label is focused. 1042 // label is focused.
975 TEST_F(LabelSelectionTest, KeyboardActions) { 1043 TEST_F(LabelSelectionTest, KeyboardActions) {
976 const base::string16 initial_text = ASCIIToUTF16("Label keyboard actions"); 1044 const base::string16 initial_text = ASCIIToUTF16("Label keyboard actions");
977 label()->SetText(initial_text); 1045 label()->SetText(initial_text);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 label()->SetObscured(false); 1102 label()->SetObscured(false);
1035 1103
1036 // For an empty label, both COPY and SELECT_ALL should be disabled. 1104 // For an empty label, both COPY and SELECT_ALL should be disabled.
1037 label()->SetText(base::string16()); 1105 label()->SetText(base::string16());
1038 ASSERT_TRUE(label()->SetSelectable(true)); 1106 ASSERT_TRUE(label()->SetSelectable(true));
1039 EXPECT_FALSE(IsMenuCommandEnabled(IDS_APP_COPY)); 1107 EXPECT_FALSE(IsMenuCommandEnabled(IDS_APP_COPY));
1040 EXPECT_FALSE(IsMenuCommandEnabled(IDS_APP_SELECT_ALL)); 1108 EXPECT_FALSE(IsMenuCommandEnabled(IDS_APP_SELECT_ALL));
1041 } 1109 }
1042 1110
1043 } // namespace views 1111 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698