| 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/button/label_button.h" | 5 #include "ui/views/controls/button/label_button.h" |
| 6 | 6 |
| 7 #include "base/macros.h" | 7 #include "base/macros.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "third_party/skia/include/core/SkBitmap.h" | 9 #include "third_party/skia/include/core/SkBitmap.h" |
| 10 #include "ui/accessibility/ax_view_state.h" | 10 #include "ui/accessibility/ax_view_state.h" |
| 11 #include "ui/base/material_design/material_design_controller.h" | 11 #include "ui/base/material_design/material_design_controller.h" |
| 12 #include "ui/base/test/material_design_controller_test_api.h" | 12 #include "ui/base/test/material_design_controller_test_api.h" |
| 13 #include "ui/events/test/event_generator.h" | 13 #include "ui/events/test/event_generator.h" |
| 14 #include "ui/gfx/canvas.h" | 14 #include "ui/gfx/canvas.h" |
| 15 #include "ui/gfx/font_list.h" | 15 #include "ui/gfx/font_list.h" |
| 16 #include "ui/gfx/geometry/size.h" | 16 #include "ui/gfx/geometry/size.h" |
| 17 #include "ui/gfx/geometry/vector2d.h" | 17 #include "ui/gfx/geometry/vector2d.h" |
| 18 #include "ui/gfx/text_utils.h" | 18 #include "ui/gfx/text_utils.h" |
| 19 #include "ui/native_theme/native_theme.h" |
| 19 #include "ui/views/animation/button_ink_drop_delegate.h" | 20 #include "ui/views/animation/button_ink_drop_delegate.h" |
| 21 #include "ui/views/style/platform_style.h" |
| 20 #include "ui/views/test/views_test_base.h" | 22 #include "ui/views/test/views_test_base.h" |
| 21 #include "ui/views/test/widget_test.h" | 23 #include "ui/views/test/widget_test.h" |
| 22 | 24 |
| 23 using base::ASCIIToUTF16; | 25 using base::ASCIIToUTF16; |
| 24 | 26 |
| 25 namespace { | 27 namespace { |
| 26 | 28 |
| 27 gfx::ImageSkia CreateTestImage(int width, int height) { | 29 gfx::ImageSkia CreateTestImage(int width, int height) { |
| 28 SkBitmap bitmap; | 30 SkBitmap bitmap; |
| 29 bitmap.allocN32Pixels(width, height); | 31 bitmap.allocN32Pixels(width, height); |
| 30 return gfx::ImageSkia::CreateFrom1xBitmap(bitmap); | 32 return gfx::ImageSkia::CreateFrom1xBitmap(bitmap); |
| 31 } | 33 } |
| 32 | 34 |
| 33 } // namespace | 35 } // namespace |
| 34 | 36 |
| 35 namespace views { | 37 namespace views { |
| 36 | 38 |
| 39 // Testing button that exposes protected methods. |
| 40 class TestLabelButton : public LabelButton { |
| 41 public: |
| 42 TestLabelButton() : LabelButton(nullptr, base::string16()) {} |
| 43 |
| 44 using LabelButton::label; |
| 45 |
| 46 private: |
| 47 DISALLOW_COPY_AND_ASSIGN(TestLabelButton); |
| 48 }; |
| 49 |
| 37 class LabelButtonTest : public test::WidgetTest { | 50 class LabelButtonTest : public test::WidgetTest { |
| 38 public: | 51 public: |
| 39 LabelButtonTest() {} | 52 LabelButtonTest() {} |
| 40 | 53 |
| 54 // Adds a LabelButton to the test Widget with the STYLE_BUTTON platform style. |
| 55 TestLabelButton* AddStyledButton(const char* label, bool is_default) { |
| 56 TestLabelButton* button = new TestLabelButton; |
| 57 button->SetText(ASCIIToUTF16(label)); |
| 58 button->SetStyle(CustomButton::STYLE_BUTTON); |
| 59 if (is_default) |
| 60 button->SetIsDefault(true); |
| 61 button_->GetWidget()->GetContentsView()->AddChildView(button); |
| 62 button->SizeToPreferredSize(); |
| 63 button->Layout(); |
| 64 return button; |
| 65 } |
| 66 |
| 41 // testing::Test: | 67 // testing::Test: |
| 42 void SetUp() override { | 68 void SetUp() override { |
| 43 WidgetTest::SetUp(); | 69 WidgetTest::SetUp(); |
| 44 // Make a Widget to host the button. This ensures appropriate borders are | 70 // Make a Widget to host the button. This ensures appropriate borders are |
| 45 // used (which could be derived from the Widget's NativeTheme). | 71 // used (which could be derived from the Widget's NativeTheme). |
| 46 test_widget_ = CreateTopLevelPlatformWidget(); | 72 test_widget_ = CreateTopLevelPlatformWidget(); |
| 47 | 73 |
| 48 button_ = new LabelButton(nullptr, base::string16()); | 74 button_ = new TestLabelButton; |
| 49 test_widget_->GetContentsView()->AddChildView(button_); | 75 test_widget_->GetContentsView()->AddChildView(button_); |
| 76 |
| 77 // Establish the expected text colors for testing changes due to state. |
| 78 themed_normal_text_color_ = button_->GetNativeTheme()->GetSystemColor( |
| 79 ui::NativeTheme::kColorId_ButtonEnabledColor); |
| 80 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 81 // The Linux theme provides a non-black highlight text color, but it's not |
| 82 // used for styled buttons. |
| 83 styled_highlight_text_color_ = themed_normal_text_color_; |
| 84 styled_normal_text_color_ = themed_normal_text_color_; |
| 85 #else |
| 86 styled_highlight_text_color_ = button_->GetNativeTheme()->GetSystemColor( |
| 87 ui::NativeTheme::kColorId_ButtonHighlightColor); |
| 88 |
| 89 // For styled buttons only, platforms other than Desktop Linux either ignore |
| 90 // NativeTheme and use a hardcoded black or (on Mac) have a NativeTheme that |
| 91 // reliably returns black. |
| 92 styled_normal_text_color_ = SK_ColorBLACK; |
| 93 #endif |
| 50 } | 94 } |
| 51 | 95 |
| 52 void TearDown() override { | 96 void TearDown() override { |
| 53 test_widget_->CloseNow(); | 97 test_widget_->CloseNow(); |
| 54 WidgetTest::TearDown(); | 98 WidgetTest::TearDown(); |
| 55 } | 99 } |
| 56 | 100 |
| 57 protected: | 101 protected: |
| 58 LabelButton* button_ = nullptr; | 102 TestLabelButton* button_ = nullptr; |
| 103 |
| 104 SkColor themed_normal_text_color_ = 0; |
| 105 SkColor styled_normal_text_color_ = 0; |
| 106 SkColor styled_highlight_text_color_ = 0; |
| 59 | 107 |
| 60 private: | 108 private: |
| 61 Widget* test_widget_ = nullptr; | 109 Widget* test_widget_ = nullptr; |
| 62 | 110 |
| 63 DISALLOW_COPY_AND_ASSIGN(LabelButtonTest); | 111 DISALLOW_COPY_AND_ASSIGN(LabelButtonTest); |
| 64 }; | 112 }; |
| 65 | 113 |
| 66 TEST_F(LabelButtonTest, Init) { | 114 TEST_F(LabelButtonTest, Init) { |
| 67 const base::string16 text(ASCIIToUTF16("abc")); | 115 const base::string16 text(ASCIIToUTF16("abc")); |
| 68 LabelButton button(NULL, text); | 116 LabelButton button(NULL, text); |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 // Increasing the spacing between the text and label should increase the size. | 331 // Increasing the spacing between the text and label should increase the size. |
| 284 button_->SetImageLabelSpacing(2 * kOriginalSpacing); | 332 button_->SetImageLabelSpacing(2 * kOriginalSpacing); |
| 285 EXPECT_GT(button_->GetPreferredSize().width(), original_width); | 333 EXPECT_GT(button_->GetPreferredSize().width(), original_width); |
| 286 | 334 |
| 287 // The button shrinks if the original spacing is restored. | 335 // The button shrinks if the original spacing is restored. |
| 288 button_->SetMinSize(gfx::Size()); | 336 button_->SetMinSize(gfx::Size()); |
| 289 button_->SetImageLabelSpacing(kOriginalSpacing); | 337 button_->SetImageLabelSpacing(kOriginalSpacing); |
| 290 EXPECT_EQ(original_width, button_->GetPreferredSize().width()); | 338 EXPECT_EQ(original_width, button_->GetPreferredSize().width()); |
| 291 } | 339 } |
| 292 | 340 |
| 293 // Make sure the label gets the width it asks for and bolding it (via | 341 // Ensure the label gets the correct style for default buttons (e.g. bolding) |
| 294 // SetDefault) causes the size to update. Regression test for crbug.com/578722 | 342 // and button size updates correctly. Regression test for crbug.com/578722. |
| 295 TEST_F(LabelButtonTest, ButtonStyleIsDefaultSize) { | 343 TEST_F(LabelButtonTest, ButtonStyleIsDefaultStyle) { |
| 296 LabelButton* button = new LabelButton(nullptr, base::ASCIIToUTF16("Save")); | 344 TestLabelButton* button = AddStyledButton("Save", false); |
| 297 button->SetStyle(CustomButton::STYLE_BUTTON); | 345 gfx::Size non_default_size = button->label()->size(); |
| 298 button_->GetWidget()->GetContentsView()->AddChildView(button); | 346 EXPECT_EQ(button->label()->GetPreferredSize().width(), |
| 299 button->SizeToPreferredSize(); | |
| 300 button->Layout(); | |
| 301 gfx::Size non_default_size = button->label_->size(); | |
| 302 EXPECT_EQ(button->label_->GetPreferredSize().width(), | |
| 303 non_default_size.width()); | 347 non_default_size.width()); |
| 348 EXPECT_FALSE(button->label()->font_list().GetFontStyle() & gfx::Font::BOLD); |
| 349 EXPECT_EQ(styled_normal_text_color_, button->label()->enabled_color()); |
| 304 button->SetIsDefault(true); | 350 button->SetIsDefault(true); |
| 305 button->SizeToPreferredSize(); | 351 button->SizeToPreferredSize(); |
| 306 button->Layout(); | 352 button->Layout(); |
| 307 EXPECT_NE(non_default_size, button->label_->size()); | 353 EXPECT_EQ(styled_highlight_text_color_, button->label()->enabled_color()); |
| 354 if (PlatformStyle::kDefaultLabelButtonHasBoldFont) { |
| 355 EXPECT_NE(non_default_size, button->label()->size()); |
| 356 EXPECT_TRUE(button->label()->font_list().GetFontStyle() & gfx::Font::BOLD); |
| 357 } else { |
| 358 EXPECT_EQ(non_default_size, button->label()->size()); |
| 359 EXPECT_FALSE(button->label()->font_list().GetFontStyle() & gfx::Font::BOLD); |
| 360 } |
| 361 } |
| 362 |
| 363 // Ensure the label gets the correct style when pressed or becoming default. |
| 364 TEST_F(LabelButtonTest, HighlightedButtonStyle) { |
| 365 #if defined(OS_MACOSX) |
| 366 // On Mac, ensure the normal and highlight colors are different, to ensure the |
| 367 // tests are actually testing something. This might be the case on other |
| 368 // platforms. |
| 369 EXPECT_NE(styled_normal_text_color_, styled_highlight_text_color_); |
| 370 #endif |
| 371 |
| 372 // For STYLE_TEXTBUTTON, the NativeTheme might not provide SK_ColorBLACK, but |
| 373 // it should be the same for normal and pressed states. |
| 374 EXPECT_EQ(themed_normal_text_color_, button_->label()->enabled_color()); |
| 375 button_->SetState(Button::STATE_PRESSED); |
| 376 EXPECT_EQ(themed_normal_text_color_, button_->label()->enabled_color()); |
| 377 |
| 378 // Add a non-default button. |
| 379 TestLabelButton* styled_button = AddStyledButton("OK", false); |
| 380 EXPECT_EQ(styled_normal_text_color_, styled_button->label()->enabled_color()); |
| 381 styled_button->SetState(Button::STATE_PRESSED); |
| 382 EXPECT_EQ(styled_highlight_text_color_, |
| 383 styled_button->label()->enabled_color()); |
| 384 |
| 385 // If there's an explicit color set for STATE_PRESSED, that should be used. |
| 386 styled_button->SetEnabledTextColors(SK_ColorRED); |
| 387 EXPECT_EQ(SK_ColorRED, styled_button->label()->enabled_color()); |
| 388 |
| 389 // Test becoming default after adding to the Widget. |
| 390 TestLabelButton* default_after = AddStyledButton("OK", false); |
| 391 EXPECT_EQ(styled_normal_text_color_, default_after->label()->enabled_color()); |
| 392 default_after->SetIsDefault(true); |
| 393 EXPECT_EQ(styled_highlight_text_color_, |
| 394 default_after->label()->enabled_color()); |
| 395 |
| 396 // Test becoming default before adding to the Widget. |
| 397 TestLabelButton* default_before = AddStyledButton("OK", true); |
| 398 EXPECT_EQ(styled_highlight_text_color_, |
| 399 default_before->label()->enabled_color()); |
| 308 } | 400 } |
| 309 | 401 |
| 310 // A ButtonInkDropDelegate that tracks the last hover state requested. | 402 // A ButtonInkDropDelegate that tracks the last hover state requested. |
| 311 class TestButtonInkDropDelegate : public ButtonInkDropDelegate { | 403 class TestButtonInkDropDelegate : public ButtonInkDropDelegate { |
| 312 public: | 404 public: |
| 313 TestButtonInkDropDelegate(InkDropHost* ink_drop_host, View* view) | 405 TestButtonInkDropDelegate(InkDropHost* ink_drop_host, View* view) |
| 314 : ButtonInkDropDelegate(ink_drop_host, view), is_hovered_(false) {} | 406 : ButtonInkDropDelegate(ink_drop_host, view), is_hovered_(false) {} |
| 315 | 407 |
| 316 ~TestButtonInkDropDelegate() override {} | 408 ~TestButtonInkDropDelegate() override {} |
| 317 | 409 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 | 504 |
| 413 // Verifies the target event handler View is the |LabelButton| and not any of | 505 // Verifies the target event handler View is the |LabelButton| and not any of |
| 414 // the child Views. | 506 // the child Views. |
| 415 TEST_F(InkDropLabelButtonTest, TargetEventHandler) { | 507 TEST_F(InkDropLabelButtonTest, TargetEventHandler) { |
| 416 View* target_view = widget_->GetRootView()->GetEventHandlerForPoint( | 508 View* target_view = widget_->GetRootView()->GetEventHandlerForPoint( |
| 417 button_->bounds().CenterPoint()); | 509 button_->bounds().CenterPoint()); |
| 418 EXPECT_EQ(button_, target_view); | 510 EXPECT_EQ(button_, target_view); |
| 419 } | 511 } |
| 420 | 512 |
| 421 } // namespace views | 513 } // namespace views |
| OLD | NEW |