summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorderat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-06 23:45:52 +0000
committerderat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-06 23:45:52 +0000
commitb43a8979ea49b29dad4617c1a718493dd3973bf0 (patch)
tree1b7093683c5250480b36ee67802f9bdb1717427a /ui
parent33ade1dbecd20b268cd725be938f8caccc71fcda (diff)
downloadchromium_src-b43a8979ea49b29dad4617c1a718493dd3973bf0.zip
chromium_src-b43a8979ea49b29dad4617c1a718493dd3973bf0.tar.gz
chromium_src-b43a8979ea49b29dad4617c1a718493dd3973bf0.tar.bz2
aura: Draw shadows around tooltip windows.
Also, add padding around the tooltip text and disable the border when shadows are enabled. I'm also updating the existing shadow code in aura_shell to clip corner images as needed when they're too large to fit within the requested size. BUG=106507 TEST=added Review URL: http://codereview.chromium.org/8821028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113294 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/aura_shell/image_grid.cc110
-rw-r--r--ui/aura_shell/image_grid.h24
-rw-r--r--ui/aura_shell/image_grid_unittest.cc73
-rw-r--r--ui/aura_shell/shell_tooltip_manager.cc43
-rw-r--r--ui/views/widget/native_widget_aura.cc3
5 files changed, 215 insertions, 38 deletions
diff --git a/ui/aura_shell/image_grid.cc b/ui/aura_shell/image_grid.cc
index 14d69ce..99f8d90 100644
--- a/ui/aura_shell/image_grid.cc
+++ b/ui/aura_shell/image_grid.cc
@@ -13,6 +13,7 @@
#include "third_party/skia/include/core/SkXfermode.h"
using std::max;
+using std::min;
namespace aura_shell {
namespace internal {
@@ -92,45 +93,81 @@ void ImageGrid::SetSize(const gfx::Size& size) {
float center_height = size.height() - top_row_height_ - bottom_row_height_;
if (top_layer_.get()) {
- ui::Transform transform;
- transform.SetScaleX(center_width / top_layer_->bounds().width());
- transform.ConcatTranslate(left_column_width_, 0);
- top_layer_->SetTransform(transform);
+ if (center_width > 0) {
+ ui::Transform transform;
+ transform.SetScaleX(center_width / top_layer_->bounds().width());
+ transform.ConcatTranslate(left_column_width_, 0);
+ top_layer_->SetTransform(transform);
+ }
+ top_layer_->SetVisible(center_width > 0);
}
if (bottom_layer_.get()) {
- ui::Transform transform;
- transform.SetScaleX(center_width / bottom_layer_->bounds().width());
- transform.ConcatTranslate(
- left_column_width_, size.height() - bottom_layer_->bounds().height());
- bottom_layer_->SetTransform(transform);
+ if (center_width > 0) {
+ ui::Transform transform;
+ transform.SetScaleX(center_width / bottom_layer_->bounds().width());
+ transform.ConcatTranslate(
+ left_column_width_, size.height() - bottom_layer_->bounds().height());
+ bottom_layer_->SetTransform(transform);
+ }
+ bottom_layer_->SetVisible(center_width > 0);
}
if (left_layer_.get()) {
- ui::Transform transform;
- transform.SetScaleY(center_height / left_layer_->bounds().height());
- transform.ConcatTranslate(0, top_row_height_);
- left_layer_->SetTransform(transform);
+ if (center_height > 0) {
+ ui::Transform transform;
+ transform.SetScaleY(center_height / left_layer_->bounds().height());
+ transform.ConcatTranslate(0, top_row_height_);
+ left_layer_->SetTransform(transform);
+ }
+ left_layer_->SetVisible(center_height > 0);
}
if (right_layer_.get()) {
- ui::Transform transform;
- transform.SetScaleY(center_height / right_layer_->bounds().height());
- transform.ConcatTranslate(
- size.width() - right_layer_->bounds().width(), top_row_height_);
- right_layer_->SetTransform(transform);
+ if (center_height > 0) {
+ ui::Transform transform;
+ transform.SetScaleY(center_height / right_layer_->bounds().height());
+ transform.ConcatTranslate(
+ size.width() - right_layer_->bounds().width(), top_row_height_);
+ right_layer_->SetTransform(transform);
+ }
+ right_layer_->SetVisible(center_height > 0);
}
+ // Calculate the available amount of space for corner images on all sides of
+ // the grid. If the images don't fit, we need to clip them.
+ const int left = min(left_column_width_, size_.width() / 2);
+ const int right = min(right_column_width_, size_.width() - left);
+ const int top = min(top_row_height_, size_.height() / 2);
+ const int bottom = min(bottom_row_height_, size_.height() - top);
+
if (top_left_layer_.get()) {
// No transformation needed; it should be at (0, 0) and unscaled.
+ top_left_painter_->SetClipRect(
+ LayerExceedsSize(top_left_layer_.get(), gfx::Size(left, top)) ?
+ gfx::Rect(gfx::Rect(0, 0, left, top)) :
+ gfx::Rect(),
+ top_left_layer_.get());
}
if (top_right_layer_.get()) {
ui::Transform transform;
transform.SetTranslateX(size.width() - top_right_layer_->bounds().width());
top_right_layer_->SetTransform(transform);
+ top_right_painter_->SetClipRect(
+ LayerExceedsSize(top_right_layer_.get(), gfx::Size(right, top)) ?
+ gfx::Rect(top_right_layer_->bounds().width() - right, 0,
+ right, top) :
+ gfx::Rect(),
+ top_right_layer_.get());
}
if (bottom_left_layer_.get()) {
ui::Transform transform;
transform.SetTranslateY(
size.height() - bottom_left_layer_->bounds().height());
bottom_left_layer_->SetTransform(transform);
+ bottom_left_painter_->SetClipRect(
+ LayerExceedsSize(bottom_left_layer_.get(), gfx::Size(left, bottom)) ?
+ gfx::Rect(0, bottom_left_layer_->bounds().height() - bottom,
+ left, bottom) :
+ gfx::Rect(),
+ bottom_left_layer_.get());
}
if (bottom_right_layer_.get()) {
ui::Transform transform;
@@ -138,18 +175,38 @@ void ImageGrid::SetSize(const gfx::Size& size) {
size.width() - bottom_right_layer_->bounds().width(),
size.height() - bottom_right_layer_->bounds().height());
bottom_right_layer_->SetTransform(transform);
+ bottom_right_painter_->SetClipRect(
+ LayerExceedsSize(bottom_right_layer_.get(), gfx::Size(right, bottom)) ?
+ gfx::Rect(bottom_right_layer_->bounds().width() - right,
+ bottom_right_layer_->bounds().height() - bottom,
+ right, bottom) :
+ gfx::Rect(),
+ bottom_right_layer_.get());
}
if (center_layer_.get()) {
- ui::Transform transform;
- transform.SetScale(center_width / center_layer_->bounds().width(),
- center_height / center_layer_->bounds().height());
- transform.ConcatTranslate(left_column_width_, top_row_height_);
- center_layer_->SetTransform(transform);
+ if (center_width > 0 && center_height > 0) {
+ ui::Transform transform;
+ transform.SetScale(center_width / center_layer_->bounds().width(),
+ center_height / center_layer_->bounds().height());
+ transform.ConcatTranslate(left_column_width_, top_row_height_);
+ center_layer_->SetTransform(transform);
+ }
+ center_layer_->SetVisible(center_width > 0 && center_height > 0);
+ }
+}
+
+void ImageGrid::ImagePainter::SetClipRect(const gfx::Rect& clip_rect,
+ ui::Layer* layer) {
+ if (clip_rect != clip_rect_) {
+ clip_rect_ = clip_rect;
+ layer->ScheduleDraw();
}
}
void ImageGrid::ImagePainter::OnPaintLayer(gfx::Canvas* canvas) {
+ if (!clip_rect_.IsEmpty())
+ canvas->ClipRect(clip_rect_);
canvas->DrawBitmapInt(*(image_->ToSkBitmap()), 0, 0);
}
@@ -160,6 +217,13 @@ gfx::Size ImageGrid::GetImageSize(const gfx::Image* image) {
gfx::Size();
}
+// static
+bool ImageGrid::LayerExceedsSize(const ui::Layer* layer,
+ const gfx::Size& size) {
+ return layer->bounds().width() > size.width() ||
+ layer->bounds().height() > size.height();
+}
+
void ImageGrid::InitImage(const gfx::Image* image,
scoped_ptr<ui::Layer>* layer_ptr,
scoped_ptr<ImagePainter>* painter_ptr) {
diff --git a/ui/aura_shell/image_grid.h b/ui/aura_shell/image_grid.h
index a5ff264..892ab7f0 100644
--- a/ui/aura_shell/image_grid.h
+++ b/ui/aura_shell/image_grid.h
@@ -78,6 +78,19 @@ class AURA_SHELL_EXPORT ImageGrid {
return grid_->bottom_right_layer_.get();
}
+ gfx::Rect top_left_clip_rect() const {
+ return grid_->top_left_painter_->clip_rect_;
+ }
+ gfx::Rect top_right_clip_rect() const {
+ return grid_->top_right_painter_->clip_rect_;
+ }
+ gfx::Rect bottom_left_clip_rect() const {
+ return grid_->bottom_left_painter_->clip_rect_;
+ }
+ gfx::Rect bottom_right_clip_rect() const {
+ return grid_->bottom_right_painter_->clip_rect_;
+ }
+
// Returns |layer|'s bounds after applying the layer's current transform.
gfx::Rect GetTransformedLayerBounds(const ui::Layer& layer);
@@ -117,18 +130,29 @@ class AURA_SHELL_EXPORT ImageGrid {
ImagePainter(const gfx::Image* image) : image_(image) {}
virtual ~ImagePainter() {}
+ // Clips |layer| to |clip_rect|. Triggers a repaint if the clipping
+ // rectangle has changed. An empty rectangle disables clipping.
+ void SetClipRect(const gfx::Rect& clip_rect, ui::Layer* layer);
+
// ui::LayerDelegate implementation:
virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE;
private:
+ friend class TestAPI;
+
const gfx::Image* image_; // not owned
+ gfx::Rect clip_rect_;
+
DISALLOW_COPY_AND_ASSIGN(ImagePainter);
};
// Returns the dimensions of |image| if non-NULL or gfx::Size(0, 0) otherwise.
static gfx::Size GetImageSize(const gfx::Image* image);
+ // Returns true if |layer|'s bounds don't fit within |size|.
+ static bool LayerExceedsSize(const ui::Layer* layer, const gfx::Size& size);
+
// Initializes |layer_ptr| and |painter_ptr| to display |image|.
// Also adds the passed-in layer to |layer_|.
void InitImage(const gfx::Image* image,
diff --git a/ui/aura_shell/image_grid_unittest.cc b/ui/aura_shell/image_grid_unittest.cc
index e75bd403..185a0fa 100644
--- a/ui/aura_shell/image_grid_unittest.cc
+++ b/ui/aura_shell/image_grid_unittest.cc
@@ -180,7 +180,6 @@ TEST_F(ImageGridTest, SmallerSides) {
test_api.GetTransformedLayerBounds(
*test_api.top_layer()).ToString());
-
// The left layer should be flush with the left edge and stretched vertically
// between the top left corner and the bottom.
EXPECT_EQ(gfx::Rect(
@@ -197,5 +196,77 @@ TEST_F(ImageGridTest, SmallerSides) {
*test_api.right_layer()).ToString());
}
+// Test that we hide or clip layers as needed when the grid is assigned a small
+// size.
+TEST_F(ImageGridTest, TooSmall) {
+ const int kCorner = 5;
+ const int kCenter = 3;
+ const int kEdge = 3;
+
+ scoped_ptr<gfx::Image> top_left_image(
+ CreateImage(gfx::Size(kCorner, kCorner)));
+ scoped_ptr<gfx::Image> top_image(CreateImage(gfx::Size(kEdge, kEdge)));
+ scoped_ptr<gfx::Image> top_right_image(
+ CreateImage(gfx::Size(kCorner, kCorner)));
+ scoped_ptr<gfx::Image> left_image(CreateImage(gfx::Size(kEdge, kEdge)));
+ scoped_ptr<gfx::Image> center_image(CreateImage(gfx::Size(kCenter, kCenter)));
+ scoped_ptr<gfx::Image> right_image(CreateImage(gfx::Size(kEdge, kEdge)));
+ scoped_ptr<gfx::Image> bottom_left_image(
+ CreateImage(gfx::Size(kCorner, kCorner)));
+ scoped_ptr<gfx::Image> bottom_image(CreateImage(gfx::Size(kEdge, kEdge)));
+ scoped_ptr<gfx::Image> bottom_right_image(
+ CreateImage(gfx::Size(kCorner, kCorner)));
+
+ ImageGrid grid;
+ grid.Init(
+ top_left_image.get(), top_image.get(), top_right_image.get(),
+ left_image.get(), center_image.get(), right_image.get(),
+ bottom_left_image.get(), bottom_image.get(), bottom_right_image.get());
+ ImageGrid::TestAPI test_api(&grid);
+
+ // Set a size that's smaller than the combined (unscaled) corner images.
+ const gfx::Size kSmallSize(kCorner + kCorner - 3, kCorner + kCorner - 5);
+ grid.SetSize(kSmallSize);
+
+ // The scalable images around the sides and in the center should be hidden.
+ EXPECT_FALSE(test_api.top_layer()->visible());
+ EXPECT_FALSE(test_api.bottom_layer()->visible());
+ EXPECT_FALSE(test_api.left_layer()->visible());
+ EXPECT_FALSE(test_api.right_layer()->visible());
+ EXPECT_FALSE(test_api.center_layer()->visible());
+
+ // The corner images' clip rects should sum to the expected size.
+ EXPECT_EQ(kSmallSize.width(),
+ test_api.top_left_clip_rect().width() +
+ test_api.top_right_clip_rect().width());
+ EXPECT_EQ(kSmallSize.width(),
+ test_api.bottom_left_clip_rect().width() +
+ test_api.bottom_right_clip_rect().width());
+ EXPECT_EQ(kSmallSize.height(),
+ test_api.top_left_clip_rect().height() +
+ test_api.bottom_left_clip_rect().height());
+ EXPECT_EQ(kSmallSize.height(),
+ test_api.top_right_clip_rect().height() +
+ test_api.bottom_right_clip_rect().height());
+
+ // Resize the grid to be large enough to show all images.
+ const gfx::Size kLargeSize(kCorner + kCorner + kCenter,
+ kCorner + kCorner + kCenter);
+ grid.SetSize(kLargeSize);
+
+ // The scalable images should be visible now.
+ EXPECT_TRUE(test_api.top_layer()->visible());
+ EXPECT_TRUE(test_api.bottom_layer()->visible());
+ EXPECT_TRUE(test_api.left_layer()->visible());
+ EXPECT_TRUE(test_api.right_layer()->visible());
+ EXPECT_TRUE(test_api.center_layer()->visible());
+
+ // We shouldn't be clipping the corner images anymore.
+ EXPECT_TRUE(test_api.top_left_clip_rect().IsEmpty());
+ EXPECT_TRUE(test_api.top_right_clip_rect().IsEmpty());
+ EXPECT_TRUE(test_api.bottom_left_clip_rect().IsEmpty());
+ EXPECT_TRUE(test_api.bottom_right_clip_rect().IsEmpty());
+}
+
} // namespace test
} // namespace aura_shell
diff --git a/ui/aura_shell/shell_tooltip_manager.cc b/ui/aura_shell/shell_tooltip_manager.cc
index 0544ca8..ac8fa54 100644
--- a/ui/aura_shell/shell_tooltip_manager.cc
+++ b/ui/aura_shell/shell_tooltip_manager.cc
@@ -6,9 +6,11 @@
#include <vector>
+#include "base/command_line.h"
#include "base/location.h"
#include "base/string_split.h"
#include "base/time.h"
+#include "ui/aura/aura_switches.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/event.h"
#include "ui/aura/window.h"
@@ -26,14 +28,19 @@
namespace {
-SkColor kTooltipBackground = 0xFFFFFFCC;
-SkColor kTooltipBorder = 0xFF000000;
-int kTooltipBorderWidth = 1;
-int kTooltipTimeoutMs = 500;
+const SkColor kTooltipBackground = 0xFFFFFFCC;
+const SkColor kTooltipBorder = 0xFF646450;
+const int kTooltipBorderWidth = 1;
+const int kTooltipHorizontalPadding = 3;
+// TODO(derat): This padding is needed on Chrome OS devices but seems excessive
+// when running the same binary on a Linux workstation; presumably there's a
+// difference in font metrics. Rationalize this.
+const int kTooltipVerticalPadding = 2;
+const int kTooltipTimeoutMs = 500;
// FIXME: get cursor offset from actual cursor size.
-int kCursorOffsetX = 10;
-int kCursorOffsetY = 15;
+const int kCursorOffsetX = 10;
+const int kCursorOffsetY = 15;
// Maximum number of characters we allow in a tooltip.
const size_t kMaxTooltipLength = 1024;
@@ -107,8 +114,11 @@ class ShellTooltipManager::Tooltip {
Tooltip() {
label_.set_background(
views::Background::CreateSolidBackground(kTooltipBackground));
- label_.set_border(
- views::Border::CreateSolidBorder(kTooltipBorderWidth, kTooltipBorder));
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAuraNoShadows)) {
+ label_.set_border(
+ views::Border::CreateSolidBorder(kTooltipBorderWidth,
+ kTooltipBorder));
+ }
label_.set_parent_owned(false);
widget_.reset(CreateTooltip());
widget_->SetContentsView(&label_);
@@ -126,8 +136,14 @@ class ShellTooltipManager::Tooltip {
location.x(), location.y());
label_.SetText(tooltip_text);
- SetTooltipBounds(location, max_width + 2 * kTooltipBorderWidth,
- label_.GetPreferredSize().height());
+ int width = max_width + 2 * kTooltipHorizontalPadding;
+ int height = label_.GetPreferredSize().height() +
+ 2 * kTooltipVerticalPadding;
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAuraNoShadows)) {
+ width += 2 * kTooltipBorderWidth;
+ height += 2 * kTooltipBorderWidth;
+ }
+ SetTooltipBounds(location, width, height);
}
// Shows the tooltip.
@@ -167,9 +183,10 @@ class ShellTooltipManager::Tooltip {
////////////////////////////////////////////////////////////////////////////////
// ShellTooltipManager public:
-ShellTooltipManager::ShellTooltipManager() : aura::EventFilter(NULL),
- tooltip_window_(NULL),
- tooltip_(new Tooltip) {
+ShellTooltipManager::ShellTooltipManager()
+ : aura::EventFilter(NULL),
+ tooltip_window_(NULL),
+ tooltip_(new Tooltip) {
tooltip_timer_.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(kTooltipTimeoutMs),
this, &ShellTooltipManager::TooltipTimerFired);
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc
index 2bdba97..aca71bd 100644
--- a/ui/views/widget/native_widget_aura.cc
+++ b/ui/views/widget/native_widget_aura.cc
@@ -168,7 +168,8 @@ void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) {
static_cast<aura::WindowDragDropDelegate*>(this));
}
- if (window_type == Widget::InitParams::TYPE_MENU)
+ if (window_type == Widget::InitParams::TYPE_MENU ||
+ window_type == Widget::InitParams::TYPE_TOOLTIP)
window_->SetIntProperty(aura::kShadowTypeKey,
aura::SHADOW_TYPE_RECTANGULAR);
}