15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/layout.h"
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/views/border.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/image_button.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/test/views_test_base.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia CreateTestImage(int width, int height) {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap bitmap;
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bitmap.allocN32Pixels(width, height);
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef ViewsTestBase ImageButtonTest;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ImageButtonTest, Basics) {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageButton button(NULL);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Our image to paint starts empty.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(button.GetImageToPaint().isNull());
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Without an image, buttons are 16x14 by default.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("16x14", button.GetPreferredSize().ToString());
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The minimum image size should be applied even when there is no image.
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  button.SetMinimumImageSize(gfx::Size(5, 15));
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ("5x15", button.minimum_image_size().ToString());
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ("16x15", button.GetPreferredSize().ToString());
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set a normal image.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia normal_image = CreateTestImage(10, 20);
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  button.SetImage(CustomButton::STATE_NORMAL, &normal_image);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Image uses normal image for painting.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(button.GetImageToPaint().isNull());
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, button.GetImageToPaint().width());
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(20, button.GetImageToPaint().height());
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preferred size is the normal button size.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("10x20", button.GetPreferredSize().ToString());
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set a pushed image.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia pushed_image = CreateTestImage(11, 21);
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  button.SetImage(CustomButton::STATE_PRESSED, &pushed_image);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // By convention, preferred size doesn't change, even though pushed image
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is bigger.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("10x20", button.GetPreferredSize().ToString());
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We're still painting the normal image.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(button.GetImageToPaint().isNull());
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, button.GetImageToPaint().width());
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(20, button.GetImageToPaint().height());
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The minimum image size should make the preferred size bigger.
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  button.SetMinimumImageSize(gfx::Size(15, 5));
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ("15x5", button.minimum_image_size().ToString());
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ("15x20", button.GetPreferredSize().ToString());
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  button.SetMinimumImageSize(gfx::Size(15, 25));
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ("15x25", button.minimum_image_size().ToString());
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ("15x25", button.GetPreferredSize().ToString());
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ImageButtonTest, SetAndGetImage) {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ImageButton button(NULL);
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Images start as null.
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(button.GetImage(Button::STATE_NORMAL).isNull());
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(button.GetImage(Button::STATE_HOVERED).isNull());
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(button.GetImage(Button::STATE_PRESSED).isNull());
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(button.GetImage(Button::STATE_DISABLED).isNull());
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Setting images works as expected.
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::ImageSkia image1 = CreateTestImage(10, 11);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::ImageSkia image2 = CreateTestImage(20, 21);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  button.SetImage(Button::STATE_NORMAL, &image1);
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  button.SetImage(Button::STATE_HOVERED, &image2);
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      button.GetImage(Button::STATE_NORMAL).BackedBySameObjectAs(image1));
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      button.GetImage(Button::STATE_HOVERED).BackedBySameObjectAs(image2));
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(button.GetImage(Button::STATE_PRESSED).isNull());
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(button.GetImage(Button::STATE_DISABLED).isNull());
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ImageButton supports NULL image pointers.
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  button.SetImage(Button::STATE_NORMAL, NULL);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(button.GetImage(Button::STATE_NORMAL).isNull());
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ImageButtonTest, ImagePositionWithBorder) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageButton button(NULL);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia image = CreateTestImage(20, 30);
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  button.SetImage(CustomButton::STATE_NORMAL, &image);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The image should be painted at the top-left corner.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Point().ToString(),
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            button.ComputeImagePaintPosition(image).ToString());
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  button.SetBorder(views::Border::CreateEmptyBorder(10, 5, 0, 0));
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Point(5, 10).ToString(),
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            button.ComputeImagePaintPosition(image).ToString());
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  button.SetBorder(Border::NullBorder());
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  button.SetBounds(0, 0, 50, 50);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Point().ToString(),
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            button.ComputeImagePaintPosition(image).ToString());
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  button.SetImageAlignment(ImageButton::ALIGN_CENTER,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           ImageButton::ALIGN_MIDDLE);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Point(15, 10).ToString(),
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            button.ComputeImagePaintPosition(image).ToString());
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  button.SetBorder(views::Border::CreateEmptyBorder(10, 10, 0, 0));
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Point(20, 15).ToString(),
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            button.ComputeImagePaintPosition(image).ToString());
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The entire button's size should take the border into account.
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(gfx::Size(30, 40).ToString(), button.GetPreferredSize().ToString());
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The border should be added on top of the minimum image size.
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  button.SetMinimumImageSize(gfx::Size(30, 5));
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(gfx::Size(40, 40).ToString(), button.GetPreferredSize().ToString());
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ImageButtonTest, LeftAlignedMirrored) {
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ImageButton button(NULL);
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::ImageSkia image = CreateTestImage(20, 30);
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  button.SetImage(CustomButton::STATE_NORMAL, &image);
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  button.SetBounds(0, 0, 50, 30);
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  button.SetImageAlignment(ImageButton::ALIGN_LEFT,
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           ImageButton::ALIGN_BOTTOM);
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  button.SetDrawImageMirrored(true);
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Because the coordinates are flipped, we should expect this to draw as if
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // it were ALIGN_RIGHT.
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(gfx::Point(30, 0).ToString(),
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            button.ComputeImagePaintPosition(image).ToString());
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ImageButtonTest, RightAlignedMirrored) {
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ImageButton button(NULL);
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::ImageSkia image = CreateTestImage(20, 30);
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  button.SetImage(CustomButton::STATE_NORMAL, &image);
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  button.SetBounds(0, 0, 50, 30);
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  button.SetImageAlignment(ImageButton::ALIGN_RIGHT,
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           ImageButton::ALIGN_BOTTOM);
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  button.SetDrawImageMirrored(true);
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Because the coordinates are flipped, we should expect this to draw as if
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // it were ALIGN_LEFT.
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(gfx::Point(0, 0).ToString(),
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            button.ComputeImagePaintPosition(image).ToString());
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
164