summaryrefslogtreecommitdiffstats
path: root/ui/views
diff options
context:
space:
mode:
authorjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-23 22:40:23 +0000
committerjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-23 22:40:23 +0000
commit6ea8820f94bd46cc9fd521e316f6927e9ef9c130 (patch)
tree486fb690fd24db219f748a49df284ec0db69d89e /ui/views
parent7c0c33adc4845f1d5cf5c5ca85a7f353cad45324 (diff)
downloadchromium_src-6ea8820f94bd46cc9fd521e316f6927e9ef9c130.zip
chromium_src-6ea8820f94bd46cc9fd521e316f6927e9ef9c130.tar.gz
chromium_src-6ea8820f94bd46cc9fd521e316f6927e9ef9c130.tar.bz2
views: Add optional overlay image to ImageButton
This allows us to build a single set of normal / hot / pushed images, then overlay a back arrow, forward arrow, etc. on top of them, which reduces the number of new assets we need for the toolbar. Also added unit tests for ImageButton and added ImageButton to the views examples window. BUG=124708 TEST=views_unittest, manually checked ash_shell "Views example widgets" for image and behavior Review URL: https://chromiumcodereview.appspot.com/10174014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@133546 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/views')
-rw-r--r--ui/views/controls/button/image_button.cc14
-rw-r--r--ui/views/controls/button/image_button.h12
-rw-r--r--ui/views/controls/button/image_button_unittest.cc82
-rw-r--r--ui/views/examples/button_example.cc68
-rw-r--r--ui/views/examples/button_example.h9
-rw-r--r--ui/views/views.gyp1
6 files changed, 157 insertions, 29 deletions
diff --git a/ui/views/controls/button/image_button.cc b/ui/views/controls/button/image_button.cc
index 129ca26..85c705d 100644
--- a/ui/views/controls/button/image_button.cc
+++ b/ui/views/controls/button/image_button.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -48,6 +48,14 @@ void ImageButton::SetBackground(SkColor color,
SkBitmapOperations::CreateButtonBackground(color, *image, *mask);
}
+void ImageButton::SetOverlayImage(const SkBitmap* image) {
+ if (!image) {
+ overlay_image_.reset();
+ return;
+ }
+ overlay_image_ = *image;
+}
+
void ImageButton::SetImageAlignment(HorizontalAlignment h_align,
VerticalAlignment v_align) {
h_alignment_ = h_align;
@@ -85,7 +93,11 @@ void ImageButton::OnPaint(gfx::Canvas* canvas) {
if (!background_image_.empty())
canvas->DrawBitmapInt(background_image_, x, y);
+
canvas->DrawBitmapInt(img, x, y);
+
+ if (!overlay_image_.empty())
+ canvas->DrawBitmapInt(overlay_image_, x, y);
}
OnPaintFocusBorder(canvas);
}
diff --git a/ui/views/controls/button/image_button.h b/ui/views/controls/button/image_button.h
index f4260ca..3085869 100644
--- a/ui/views/controls/button/image_button.h
+++ b/ui/views/controls/button/image_button.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,6 +6,7 @@
#define UI_VIEWS_CONTROLS_BUTTON_IMAGE_BUTTON_H_
#pragma once
+#include "base/gtest_prod_util.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/views/controls/button/custom_button.h"
@@ -30,6 +31,10 @@ class VIEWS_EXPORT ImageButton : public CustomButton {
const SkBitmap* image,
const SkBitmap* mask);
+ // Set an |image| to draw on top of the normal / hot / pushed image.
+ // Pass NULL for no image.
+ void SetOverlayImage(const SkBitmap* image);
+
enum HorizontalAlignment { ALIGN_LEFT = 0,
ALIGN_CENTER,
ALIGN_RIGHT, };
@@ -63,7 +68,12 @@ class VIEWS_EXPORT ImageButton : public CustomButton {
// The background image.
SkBitmap background_image_;
+ // Image to draw on top of normal / hot / pushed image. Usually empty.
+ SkBitmap overlay_image_;
+
private:
+ FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, Basics);
+
// Image alignment.
HorizontalAlignment h_alignment_;
VerticalAlignment v_alignment_;
diff --git a/ui/views/controls/button/image_button_unittest.cc b/ui/views/controls/button/image_button_unittest.cc
new file mode 100644
index 0000000..9d9a9b1
--- /dev/null
+++ b/ui/views/controls/button/image_button_unittest.cc
@@ -0,0 +1,82 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/views/controls/button/image_button.h"
+#include "ui/views/test/views_test_base.h"
+
+namespace {
+
+SkBitmap CreateTestBitmap(int width, int height) {
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
+ bitmap.allocPixels();
+ return bitmap;
+}
+
+} // namespace
+
+namespace views {
+
+typedef ViewsTestBase ImageButtonTest;
+
+TEST_F(ImageButtonTest, Basics) {
+ ImageButton button(NULL);
+
+ // Our image to paint starts empty.
+ EXPECT_TRUE(button.GetImageToPaint().empty());
+
+ // Without a theme, buttons are 16x14 by default.
+ EXPECT_EQ("16x14", button.GetPreferredSize().ToString());
+
+ // We can set a preferred size when we have no image.
+ button.SetPreferredSize(gfx::Size(5, 15));
+ EXPECT_EQ("5x15", button.GetPreferredSize().ToString());
+
+ // Set a normal image.
+ SkBitmap normal_bitmap = CreateTestBitmap(10, 20);
+ button.SetImage(CustomButton::BS_NORMAL, &normal_bitmap);
+
+ // Image uses normal image for painting.
+ EXPECT_FALSE(button.GetImageToPaint().empty());
+ EXPECT_EQ(10, button.GetImageToPaint().width());
+ EXPECT_EQ(20, button.GetImageToPaint().height());
+
+ // Preferred size is the normal button size.
+ EXPECT_EQ("10x20", button.GetPreferredSize().ToString());
+
+ // Set a pushed image.
+ SkBitmap pushed_bitmap = CreateTestBitmap(11, 21);
+ button.SetImage(CustomButton::BS_PUSHED, &pushed_bitmap);
+
+ // By convention, preferred size doesn't change, even though pushed image
+ // is bigger.
+ EXPECT_EQ("10x20", button.GetPreferredSize().ToString());
+
+ // We're still painting the normal image.
+ EXPECT_FALSE(button.GetImageToPaint().empty());
+ EXPECT_EQ(10, button.GetImageToPaint().width());
+ EXPECT_EQ(20, button.GetImageToPaint().height());
+
+ // Set an overlay bitmap.
+ SkBitmap overlay_bitmap = CreateTestBitmap(12, 22);
+ button.SetOverlayImage(&overlay_bitmap);
+ EXPECT_EQ(12, button.overlay_image_.width());
+ EXPECT_EQ(22, button.overlay_image_.height());
+
+ // By convention, preferred size doesn't change, even though pushed image
+ // is bigger.
+ EXPECT_EQ("10x20", button.GetPreferredSize().ToString());
+
+ // We're still painting the normal image.
+ EXPECT_FALSE(button.GetImageToPaint().empty());
+ EXPECT_EQ(10, button.GetImageToPaint().width());
+ EXPECT_EQ(20, button.GetImageToPaint().height());
+
+ // Reset the overlay bitmap.
+ button.SetOverlayImage(NULL);
+ EXPECT_TRUE(button.overlay_image_.empty());
+}
+
+} // namespace views
diff --git a/ui/views/examples/button_example.cc b/ui/views/examples/button_example.cc
index 39fa769..fec2d1c 100644
--- a/ui/views/examples/button_example.cc
+++ b/ui/views/examples/button_example.cc
@@ -8,15 +8,22 @@
#include "grit/ui_resources.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image.h"
-#include "ui/views/controls/button/checkbox.h"
-#include "ui/views/layout/fill_layout.h"
+#include "ui/views/controls/button/image_button.h"
+#include "ui/views/controls/button/text_button.h"
+#include "ui/views/layout/box_layout.h"
#include "ui/views/view.h"
+namespace {
+const int kLayoutSpacing = 10; // pixels
+} // namespace
+
namespace views {
namespace examples {
ButtonExample::ButtonExample()
- : ExampleBase("Text Button"),
+ : ExampleBase("Button"),
+ text_button_(NULL),
+ image_button_(NULL),
alignment_(TextButton::ALIGN_LEFT),
use_native_theme_border_(false),
icon_(NULL),
@@ -29,10 +36,22 @@ ButtonExample::~ButtonExample() {
}
void ButtonExample::CreateExampleView(View* container) {
- TextButton* tb = new TextButton(this, ASCIIToUTF16("Button"));
- button_ = tb;
- container->SetLayoutManager(new FillLayout);
- container->AddChildView(button_);
+ container->SetLayoutManager(
+ new BoxLayout(BoxLayout::kVertical, 0, 0, kLayoutSpacing));
+
+ text_button_ = new TextButton(this, ASCIIToUTF16("Text Button"));
+ container->AddChildView(text_button_);
+
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ image_button_ = new ImageButton(this);
+ image_button_->SetImage(ImageButton::BS_NORMAL,
+ rb.GetImageNamed(IDR_CLOSE).ToSkBitmap());
+ image_button_->SetImage(ImageButton::BS_HOT,
+ rb.GetImageNamed(IDR_CLOSE_H).ToSkBitmap());
+ image_button_->SetImage(ImageButton::BS_PUSHED,
+ rb.GetImageNamed(IDR_CLOSE_P).ToSkBitmap());
+ image_button_->SetOverlayImage(rb.GetImageNamed(IDR_MENU_CHECK).ToSkBitmap());
+ container->AddChildView(image_button_);
}
void ButtonExample::ButtonPressed(Button* sender, const Event& event) {
@@ -41,29 +60,29 @@ void ButtonExample::ButtonPressed(Button* sender, const Event& event) {
if (event.IsControlDown()) {
if (event.IsShiftDown()) {
if (event.IsAltDown()) {
- button_->SetMultiLine(!button_->multi_line());
- if (button_->multi_line()) {
- button_->SetText(ASCIIToUTF16("Multi-line text\n") +
+ text_button_->SetMultiLine(!text_button_->multi_line());
+ if (text_button_->multi_line()) {
+ text_button_->SetText(ASCIIToUTF16("Multi-line text\n") +
ASCIIToUTF16("is here to stay all the way!\n") +
ASCIIToUTF16("123"));
} else {
- button_->SetText(ASCIIToUTF16("Button"));
+ text_button_->SetText(ASCIIToUTF16("Button"));
}
} else {
- switch(button_->icon_placement()) {
+ switch(text_button_->icon_placement()) {
case TextButton::ICON_ON_LEFT:
- button_->set_icon_placement(TextButton::ICON_ON_RIGHT);
+ text_button_->set_icon_placement(TextButton::ICON_ON_RIGHT);
break;
case TextButton::ICON_ON_RIGHT:
- button_->set_icon_placement(TextButton::ICON_ON_LEFT);
+ text_button_->set_icon_placement(TextButton::ICON_ON_LEFT);
break;
}
}
} else if (event.IsAltDown()) {
- if (button_->HasIcon())
- button_->SetIcon(SkBitmap());
+ if (text_button_->HasIcon())
+ text_button_->SetIcon(SkBitmap());
else
- button_->SetIcon(*icon_);
+ text_button_->SetIcon(*icon_);
} else {
switch(alignment_) {
case TextButton::ALIGN_LEFT:
@@ -76,30 +95,31 @@ void ButtonExample::ButtonPressed(Button* sender, const Event& event) {
alignment_ = TextButton::ALIGN_LEFT;
break;
}
- button_->set_alignment(alignment_);
+ text_button_->set_alignment(alignment_);
}
} else if (event.IsShiftDown()) {
if (event.IsAltDown()) {
- if (button_->text().length() < 10) {
- button_->SetText(
+ if (text_button_->text().length() < 10) {
+ text_button_->SetText(
ASCIIToUTF16("Startof") +
ASCIIToUTF16("ReallyReallyReallyReallyReallyReallyReally") +
ASCIIToUTF16("ReallyReallyReallyReallyReallyReallyReally") +
ASCIIToUTF16("ReallyReallyReallyReallyReallyReallyReally") +
ASCIIToUTF16("LongButtonText"));
} else {
- button_->SetText(ASCIIToUTF16("Button"));
+ text_button_->SetText(ASCIIToUTF16("Button"));
}
} else {
use_native_theme_border_ = !use_native_theme_border_;
if (use_native_theme_border_)
- button_->set_border(new TextButtonNativeThemeBorder(button_));
+ text_button_->set_border(new TextButtonNativeThemeBorder(text_button_));
else
- button_->set_border(new TextButtonBorder());
+ text_button_->set_border(new TextButtonBorder());
}
} else if (event.IsAltDown()) {
- button_->SetIsDefault(!button_->is_default());
+ text_button_->SetIsDefault(!text_button_->is_default());
}
+ example_view()->GetLayoutManager()->Layout(example_view());
}
} // namespace examples
diff --git a/ui/views/examples/button_example.h b/ui/views/examples/button_example.h
index 64b914f..da0970c 100644
--- a/ui/views/examples/button_example.h
+++ b/ui/views/examples/button_example.h
@@ -12,6 +12,8 @@
#include "ui/views/examples/example_base.h"
namespace views {
+
+class ImageButton;
class View;
namespace examples {
@@ -29,15 +31,16 @@ class ButtonExample : public ExampleBase, public ButtonListener {
// Overridden from ButtonListener:
virtual void ButtonPressed(Button* sender, const Event& event) OVERRIDE;
- // The only control in this test.
- TextButton* button_;
+ // Example buttons.
+ TextButton* text_button_;
+ ImageButton* image_button_;
// Values used to modify the look and feel of the button.
TextButton::TextAlignment alignment_;
bool use_native_theme_border_;
const SkBitmap* icon_;
- // The number of times the button is pressed.
+ // The number of times the buttons are pressed.
int count_;
DISALLOW_COPY_AND_ASSIGN(ButtonExample);
diff --git a/ui/views/views.gyp b/ui/views/views.gyp
index f28e810..d2db8c5 100644
--- a/ui/views/views.gyp
+++ b/ui/views/views.gyp
@@ -467,6 +467,7 @@
'animation/bounds_animator_unittest.cc',
'bubble/bubble_delegate_unittest.cc',
'bubble/bubble_frame_view_unittest.cc',
+ 'controls/button/image_button_unittest.cc',
'controls/combobox/native_combobox_views_unittest.cc',
'controls/label_unittest.cc',
'controls/menu/menu_model_adapter_unittest.cc',