summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-28 17:52:40 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-28 17:52:40 +0000
commitc6a2e6c13da6d7e12a09a21b3f66473e82943967 (patch)
tree05d4934afcf5fd07f8339ad5d7b1e7a1415be5a4
parent8dae8e1278013adbce40e80465ad0706d2c76a39 (diff)
downloadchromium_src-c6a2e6c13da6d7e12a09a21b3f66473e82943967.zip
chromium_src-c6a2e6c13da6d7e12a09a21b3f66473e82943967.tar.gz
chromium_src-c6a2e6c13da6d7e12a09a21b3f66473e82943967.tar.bz2
tabs: Add some empty padding around the close button.
The empty padding makes it easier to close tabs using touch events. BUG=144696, 145258 Review URL: https://chromiumcodereview.appspot.com/10879104 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@153696 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/ui/views/tabs/base_tab.cc21
-rw-r--r--chrome/browser/ui/views/tabs/tab.cc20
-rw-r--r--ui/views/controls/button/image_button.cc42
-rw-r--r--ui/views/controls/button/image_button.h4
-rw-r--r--ui/views/controls/button/image_button_unittest.cc27
5 files changed, 96 insertions, 18 deletions
diff --git a/chrome/browser/ui/views/tabs/base_tab.cc b/chrome/browser/ui/views/tabs/base_tab.cc
index 356019b..11c3def 100644
--- a/chrome/browser/ui/views/tabs/base_tab.cc
+++ b/chrome/browser/ui/views/tabs/base_tab.cc
@@ -31,6 +31,10 @@
#include "ui/gfx/font.h"
#include "ui/views/controls/button/image_button.h"
+#if defined(USE_ASH)
+#include "ui/aura/env.h"
+#endif
+
// How long the pulse throb takes.
static const int kPulseDurationMs = 200;
@@ -47,6 +51,23 @@ class BaseTab::TabCloseButton : public views::ImageButton {
explicit TabCloseButton(BaseTab* tab) : views::ImageButton(tab), tab_(tab) {}
virtual ~TabCloseButton() {}
+ // Overridden from views::View.
+ virtual View* GetEventHandlerForPoint(const gfx::Point& point) OVERRIDE {
+ // Ignore the padding set on the button.
+ gfx::Rect rect = GetContentsBounds();
+
+#if defined(USE_ASH)
+ // Include the padding in hit-test for touch events.
+ if (aura::Env::GetInstance()->is_touch_down())
+ rect = GetLocalBounds();
+#elif defined(OS_WIN)
+ // TODO(sky): Use local-bounds if a touch-point is active.
+ // http://crbug.com/145258
+#endif
+
+ return rect.Contains(point) ? this : NULL;
+ }
+
virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
if (tab_->controller())
tab_->controller()->OnMouseEventInTab(this, event);
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc
index fcebe30..5ded330 100644
--- a/chrome/browser/ui/views/tabs/tab.cc
+++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -415,9 +415,23 @@ void Tab::Layout() {
int close_button_top = top_padding() + kCloseButtonVertFuzz +
(content_height - close_button_size.height()) / 2;
// If the ratio of the close button size to tab width exceeds the maximum.
- close_button()->SetBounds(lb.width() + kCloseButtonHorzFuzz,
- close_button_top, close_button_size.width(),
- close_button_size.height());
+ // The close button should be as large as possible so that there is a larger
+ // hit-target for touch events. So the close button bounds extends to the
+ // edges of the tab. However, the larger hit-target should be active only
+ // for mouse events, and the close-image should show up in the right place.
+ // So a border is added to the button with necessary padding. The close
+ // button (BaseTab::TabCloseButton) makes sure the padding is a hit-target
+ // only for touch events.
+ int top_border = close_button_top;
+ int bottom_border = height() - (close_button_size.height() + top_border);
+ int left_border = kCloseButtonHorzFuzz;
+ int right_border = width() - (lb.width() + close_button_size.width() +
+ left_border);
+ close_button()->set_border(views::Border::CreateEmptyBorder(top_border,
+ left_border, bottom_border, right_border));
+ close_button()->SetBounds(lb.width(), 0,
+ close_button_size.width() + left_border + right_border,
+ close_button_size.height() + top_border + bottom_border);
close_button()->SetVisible(true);
} else {
close_button()->SetBounds(0, 0, 0, 0);
diff --git a/ui/views/controls/button/image_button.cc b/ui/views/controls/button/image_button.cc
index 476d80c..b111780 100644
--- a/ui/views/controls/button/image_button.cc
+++ b/ui/views/controls/button/image_button.cc
@@ -80,25 +80,14 @@ void ImageButton::OnPaint(gfx::Canvas* canvas) {
gfx::ImageSkia img = GetImageToPaint();
if (!img.isNull()) {
- int x = 0, y = 0;
-
- if (h_alignment_ == ALIGN_CENTER)
- x = (width() - img.width()) / 2;
- else if (h_alignment_ == ALIGN_RIGHT)
- x = width() - img.width();
-
- if (v_alignment_ == ALIGN_MIDDLE)
- y = (height() - img.height()) / 2;
- else if (v_alignment_ == ALIGN_BOTTOM)
- y = height() - img.height();
-
+ gfx::Point position = ComputeImagePaintPosition(img);
if (!background_image_.isNull())
- canvas->DrawImageInt(background_image_, x, y);
+ canvas->DrawImageInt(background_image_, position.x(), position.y());
- canvas->DrawImageInt(img, x, y);
+ canvas->DrawImageInt(img, position.x(), position.y());
if (!overlay_image_.isNull())
- canvas->DrawImageInt(overlay_image_, x, y);
+ canvas->DrawImageInt(overlay_image_, position.x(), position.y());
}
OnPaintFocusBorder(canvas);
}
@@ -120,6 +109,29 @@ gfx::ImageSkia ImageButton::GetImageToPaint() {
}
////////////////////////////////////////////////////////////////////////////////
+// ImageButton, private:
+
+gfx::Point ImageButton::ComputeImagePaintPosition(const gfx::ImageSkia& image) {
+ int x = 0, y = 0;
+ gfx::Rect rect = GetContentsBounds();
+
+ if (h_alignment_ == ALIGN_CENTER)
+ x = (rect.width() - image.width()) / 2;
+ else if (h_alignment_ == ALIGN_RIGHT)
+ x = rect.width() - image.width();
+
+ if (v_alignment_ == ALIGN_MIDDLE)
+ y = (rect.height() - image.height()) / 2;
+ else if (v_alignment_ == ALIGN_BOTTOM)
+ y = rect.height() - image.height();
+
+ x += rect.x();
+ y += rect.y();
+
+ return gfx::Point(x, y);
+}
+
+////////////////////////////////////////////////////////////////////////////////
// ToggleImageButton, public:
ToggleImageButton::ToggleImageButton(ButtonListener* listener)
diff --git a/ui/views/controls/button/image_button.h b/ui/views/controls/button/image_button.h
index 215a9ac..e34e176 100644
--- a/ui/views/controls/button/image_button.h
+++ b/ui/views/controls/button/image_button.h
@@ -79,6 +79,10 @@ class VIEWS_EXPORT ImageButton : public CustomButton {
private:
FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, Basics);
+ FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, ImagePositionWithBorder);
+
+ // Returns the correct position of the image for painting.
+ gfx::Point ComputeImagePaintPosition(const gfx::ImageSkia& image);
// Image alignment.
HorizontalAlignment h_alignment_;
diff --git a/ui/views/controls/button/image_button_unittest.cc b/ui/views/controls/button/image_button_unittest.cc
index f95eb74..9b71964 100644
--- a/ui/views/controls/button/image_button_unittest.cc
+++ b/ui/views/controls/button/image_button_unittest.cc
@@ -80,4 +80,31 @@ TEST_F(ImageButtonTest, Basics) {
EXPECT_TRUE(button.overlay_image_.isNull());
}
+TEST_F(ImageButtonTest, ImagePositionWithBorder) {
+ ImageButton button(NULL);
+ gfx::ImageSkia image = CreateTestImage(20, 30);
+ button.SetImage(CustomButton::BS_NORMAL, &image);
+
+ // The image should be painted at the top-left corner.
+ EXPECT_EQ(gfx::Point().ToString(),
+ button.ComputeImagePaintPosition(image).ToString());
+
+ button.set_border(views::Border::CreateEmptyBorder(10, 5, 0, 0));
+ EXPECT_EQ(gfx::Point(5, 10).ToString(),
+ button.ComputeImagePaintPosition(image).ToString());
+
+ button.set_border(NULL);
+ button.SetBounds(0, 0, 50, 50);
+ EXPECT_EQ(gfx::Point().ToString(),
+ button.ComputeImagePaintPosition(image).ToString());
+
+ button.SetImageAlignment(ImageButton::ALIGN_CENTER,
+ ImageButton::ALIGN_MIDDLE);
+ EXPECT_EQ(gfx::Point(15, 10).ToString(),
+ button.ComputeImagePaintPosition(image).ToString());
+ button.set_border(views::Border::CreateEmptyBorder(10, 10, 0, 0));
+ EXPECT_EQ(gfx::Point(20, 15).ToString(),
+ button.ComputeImagePaintPosition(image).ToString());
+}
+
} // namespace views