summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/wm/image_grid.cc12
-rw-r--r--ash/wm/image_grid.h28
-rw-r--r--ash/wm/image_grid_unittest.cc149
-rw-r--r--ash/wm/resize_shadow.cc207
-rw-r--r--ash/wm/resize_shadow.h38
-rw-r--r--ash/wm/shadow.cc16
-rw-r--r--ui/resources/ui_resources.grd8
7 files changed, 211 insertions, 247 deletions
diff --git a/ash/wm/image_grid.cc b/ash/wm/image_grid.cc
index f8b87e9..c9c341f 100644
--- a/ash/wm/image_grid.cc
+++ b/ash/wm/image_grid.cc
@@ -203,6 +203,18 @@ void ImageGrid::SetSize(const gfx::Size& size) {
}
}
+void ImageGrid::SetContentBounds(const gfx::Rect& content_bounds) {
+ SetSize(
+ gfx::Size(
+ content_bounds.width() + left_image_width_ + right_image_width_,
+ content_bounds.height() + top_image_height_ + bottom_image_height_));
+ layer_->SetBounds(
+ gfx::Rect(content_bounds.x() - left_image_width_,
+ content_bounds.y() - top_image_height_,
+ layer_->bounds().width(),
+ layer_->bounds().height()));
+}
+
void ImageGrid::ImagePainter::SetClipRect(const gfx::Rect& clip_rect,
ui::Layer* layer) {
if (clip_rect != clip_rect_) {
diff --git a/ash/wm/image_grid.h b/ash/wm/image_grid.h
index aedf002..5794a74 100644
--- a/ash/wm/image_grid.h
+++ b/ash/wm/image_grid.h
@@ -64,19 +64,6 @@ class ASH_EXPORT ImageGrid {
class ASH_EXPORT TestAPI {
public:
TestAPI(ImageGrid* grid) : grid_(grid) {}
- ui::Layer* top_left_layer() const { return grid_->top_left_layer_.get(); }
- ui::Layer* top_layer() const { return grid_->top_layer_.get(); }
- ui::Layer* top_right_layer() const { return grid_->top_right_layer_.get(); }
- ui::Layer* left_layer() const { return grid_->left_layer_.get(); }
- ui::Layer* center_layer() const { return grid_->center_layer_.get(); }
- ui::Layer* right_layer() const { return grid_->right_layer_.get(); }
- ui::Layer* bottom_left_layer() const {
- return grid_->bottom_left_layer_.get();
- }
- ui::Layer* bottom_layer() const { return grid_->bottom_layer_.get(); }
- ui::Layer* bottom_right_layer() const {
- return grid_->bottom_right_layer_.get();
- }
gfx::Rect top_left_clip_rect() const {
return grid_->top_left_painter_->clip_rect_;
@@ -109,6 +96,17 @@ class ASH_EXPORT ImageGrid {
int left_image_width() const { return left_image_width_; }
int right_image_width() const { return right_image_width_; }
+ // Visible to allow independent layer animations and for testing.
+ ui::Layer* top_left_layer() const { return top_left_layer_.get(); }
+ ui::Layer* top_layer() const { return top_layer_.get(); }
+ ui::Layer* top_right_layer() const { return top_right_layer_.get(); }
+ ui::Layer* left_layer() const { return left_layer_.get(); }
+ ui::Layer* center_layer() const { return center_layer_.get(); }
+ ui::Layer* right_layer() const { return right_layer_.get(); }
+ ui::Layer* bottom_left_layer() const { return bottom_left_layer_.get(); }
+ ui::Layer* bottom_layer() const { return bottom_layer_.get(); }
+ ui::Layer* bottom_right_layer() const { return bottom_right_layer_.get(); }
+
// Sets the grid to display the passed-in images (any of which can be NULL).
// Ownership of the images remains with the caller. May be called more than
// once to switch images.
@@ -124,6 +122,10 @@ class ASH_EXPORT ImageGrid {
void SetSize(const gfx::Size& size);
+ // Sets the grid to a position and size such that the inner edges of the top,
+ // bottom, left and right images will be flush with |content_bounds|.
+ void SetContentBounds(const gfx::Rect& content_bounds);
+
private:
// Delegate responsible for painting a specific image on a layer.
class ImagePainter : public ui::LayerDelegate {
diff --git a/ash/wm/image_grid_unittest.cc b/ash/wm/image_grid_unittest.cc
index e578467..715ddb9 100644
--- a/ash/wm/image_grid_unittest.cc
+++ b/ash/wm/image_grid_unittest.cc
@@ -43,15 +43,15 @@ TEST_F(ImageGridTest, Basic) {
image_BxB.get(), image_1xB.get(), image_BxB.get());
ImageGrid::TestAPI test_api(&grid);
- ASSERT_TRUE(test_api.top_left_layer() != NULL);
- ASSERT_TRUE(test_api.top_layer() != NULL);
- ASSERT_TRUE(test_api.top_right_layer() != NULL);
- ASSERT_TRUE(test_api.left_layer() != NULL);
- ASSERT_TRUE(test_api.center_layer() != NULL);
- ASSERT_TRUE(test_api.right_layer() != NULL);
- ASSERT_TRUE(test_api.bottom_left_layer() != NULL);
- ASSERT_TRUE(test_api.bottom_layer() != NULL);
- ASSERT_TRUE(test_api.bottom_right_layer() != NULL);
+ ASSERT_TRUE(grid.top_left_layer() != NULL);
+ ASSERT_TRUE(grid.top_layer() != NULL);
+ ASSERT_TRUE(grid.top_right_layer() != NULL);
+ ASSERT_TRUE(grid.left_layer() != NULL);
+ ASSERT_TRUE(grid.center_layer() != NULL);
+ ASSERT_TRUE(grid.right_layer() != NULL);
+ ASSERT_TRUE(grid.bottom_left_layer() != NULL);
+ ASSERT_TRUE(grid.bottom_layer() != NULL);
+ ASSERT_TRUE(grid.bottom_right_layer() != NULL);
const gfx::Size size(20, 30);
grid.SetSize(size);
@@ -59,33 +59,33 @@ TEST_F(ImageGridTest, Basic) {
// The top-left layer should be flush with the top-left corner and unscaled.
EXPECT_EQ(gfx::Rect(0, 0, kBorder, kBorder).ToString(),
test_api.GetTransformedLayerBounds(
- *test_api.top_left_layer()).ToString());
+ *grid.top_left_layer()).ToString());
// The top layer should be flush with the top edge and stretched horizontally
// between the two top corners.
EXPECT_EQ(gfx::Rect(
kBorder, 0, size.width() - 2 * kBorder, kBorder).ToString(),
test_api.GetTransformedLayerBounds(
- *test_api.top_layer()).ToString());
+ *grid.top_layer()).ToString());
// The top-right layer should be flush with the top-right corner and unscaled.
EXPECT_EQ(gfx::Rect(size.width() - kBorder, 0, kBorder, kBorder).ToString(),
test_api.GetTransformedLayerBounds(
- *test_api.top_right_layer()).ToString());
+ *grid.top_right_layer()).ToString());
// The left layer should be flush with the left edge and stretched vertically
// between the two left corners.
EXPECT_EQ(gfx::Rect(
0, kBorder, kBorder, size.height() - 2 * kBorder).ToString(),
test_api.GetTransformedLayerBounds(
- *test_api.left_layer()).ToString());
+ *grid.left_layer()).ToString());
// The center layer should fill the space in the middle of the grid.
EXPECT_EQ(gfx::Rect(
kBorder, kBorder, size.width() - 2 * kBorder,
size.height() - 2 * kBorder).ToString(),
test_api.GetTransformedLayerBounds(
- *test_api.center_layer()).ToString());
+ *grid.center_layer()).ToString());
// The right layer should be flush with the right edge and stretched
// vertically between the two right corners.
@@ -93,13 +93,13 @@ TEST_F(ImageGridTest, Basic) {
size.width() - kBorder, kBorder,
kBorder, size.height() - 2 * kBorder).ToString(),
test_api.GetTransformedLayerBounds(
- *test_api.right_layer()).ToString());
+ *grid.right_layer()).ToString());
// The bottom-left layer should be flush with the bottom-left corner and
// unscaled.
EXPECT_EQ(gfx::Rect(0, size.height() - kBorder, kBorder, kBorder).ToString(),
test_api.GetTransformedLayerBounds(
- *test_api.bottom_left_layer()).ToString());
+ *grid.bottom_left_layer()).ToString());
// The bottom layer should be flush with the bottom edge and stretched
// horizontally between the two bottom corners.
@@ -107,7 +107,7 @@ TEST_F(ImageGridTest, Basic) {
kBorder, size.height() - kBorder,
size.width() - 2 * kBorder, kBorder).ToString(),
test_api.GetTransformedLayerBounds(
- *test_api.bottom_layer()).ToString());
+ *grid.bottom_layer()).ToString());
// The bottom-right layer should be flush with the bottom-right corner and
// unscaled.
@@ -115,7 +115,38 @@ TEST_F(ImageGridTest, Basic) {
size.width() - kBorder, size.height() - kBorder,
kBorder, kBorder).ToString(),
test_api.GetTransformedLayerBounds(
- *test_api.bottom_right_layer()).ToString());
+ *grid.bottom_right_layer()).ToString());
+}
+
+// Test that an ImageGrid's layers are transformed correctly when
+// SetContentBounds() is called.
+TEST_F(ImageGridTest, SetContentBounds) {
+ // Size of the images around the grid's border.
+ const int kBorder = 2;
+
+ scoped_ptr<gfx::Image> image_1x1(CreateImage(gfx::Size(1, 1)));
+ scoped_ptr<gfx::Image> image_1xB(CreateImage(gfx::Size(1, kBorder)));
+ scoped_ptr<gfx::Image> image_Bx1(CreateImage(gfx::Size(kBorder, 1)));
+ scoped_ptr<gfx::Image> image_BxB(CreateImage(gfx::Size(kBorder, kBorder)));
+
+ ImageGrid grid;
+ grid.SetImages(image_BxB.get(), image_1xB.get(), image_BxB.get(),
+ image_Bx1.get(), image_1x1.get(), image_Bx1.get(),
+ image_BxB.get(), image_1xB.get(), image_BxB.get());
+
+ ImageGrid::TestAPI test_api(&grid);
+
+ const gfx::Point origin(5, 10);
+ const gfx::Size size(20, 30);
+ grid.SetContentBounds(gfx::Rect(origin, size));
+
+ // The master layer is positioned above the top-left corner of the content
+ // bounds and has height/width that contain the grid and bounds.
+ EXPECT_EQ(gfx::Rect(origin.x() - kBorder,
+ origin.y() - kBorder,
+ size.width() + 2 * kBorder,
+ size.height() + 2 * kBorder).ToString(),
+ test_api.GetTransformedLayerBounds(*grid.layer()).ToString());
}
// Check that we don't crash if only a single image is supplied.
@@ -129,15 +160,15 @@ TEST_F(ImageGridTest, SingleImage) {
NULL, NULL, NULL);
ImageGrid::TestAPI test_api(&grid);
- EXPECT_TRUE(test_api.top_left_layer() == NULL);
- ASSERT_TRUE(test_api.top_layer() != NULL);
- EXPECT_TRUE(test_api.top_right_layer() == NULL);
- EXPECT_TRUE(test_api.left_layer() == NULL);
- EXPECT_TRUE(test_api.center_layer() == NULL);
- EXPECT_TRUE(test_api.right_layer() == NULL);
- EXPECT_TRUE(test_api.bottom_left_layer() == NULL);
- EXPECT_TRUE(test_api.bottom_layer() == NULL);
- EXPECT_TRUE(test_api.bottom_right_layer() == NULL);
+ EXPECT_TRUE(grid.top_left_layer() == NULL);
+ ASSERT_TRUE(grid.top_layer() != NULL);
+ EXPECT_TRUE(grid.top_right_layer() == NULL);
+ EXPECT_TRUE(grid.left_layer() == NULL);
+ EXPECT_TRUE(grid.center_layer() == NULL);
+ EXPECT_TRUE(grid.right_layer() == NULL);
+ EXPECT_TRUE(grid.bottom_left_layer() == NULL);
+ EXPECT_TRUE(grid.bottom_layer() == NULL);
+ EXPECT_TRUE(grid.bottom_right_layer() == NULL);
const gfx::Size kSize(10, 10);
grid.SetSize(kSize);
@@ -146,7 +177,7 @@ TEST_F(ImageGridTest, SingleImage) {
// shouldn't be scaled vertically.
EXPECT_EQ(gfx::Rect(0, 0, kSize.width(), kBorder).ToString(),
test_api.GetTransformedLayerBounds(
- *test_api.top_layer()).ToString());
+ *grid.top_layer()).ToString());
}
// Check that we don't crash when we reset existing images to NULL and
@@ -162,30 +193,30 @@ TEST_F(ImageGridTest, ResetImages) {
// Only the top edge has a layer.
ImageGrid::TestAPI test_api(&grid);
- ASSERT_TRUE(test_api.top_left_layer() == NULL);
- ASSERT_FALSE(test_api.top_layer() == NULL);
- ASSERT_TRUE(test_api.top_right_layer() == NULL);
- ASSERT_TRUE(test_api.left_layer() == NULL);
- ASSERT_TRUE(test_api.center_layer() == NULL);
- ASSERT_TRUE(test_api.right_layer() == NULL);
- ASSERT_TRUE(test_api.bottom_left_layer() == NULL);
- ASSERT_TRUE(test_api.bottom_layer() == NULL);
- ASSERT_TRUE(test_api.bottom_right_layer() == NULL);
+ ASSERT_TRUE(grid.top_left_layer() == NULL);
+ ASSERT_FALSE(grid.top_layer() == NULL);
+ ASSERT_TRUE(grid.top_right_layer() == NULL);
+ ASSERT_TRUE(grid.left_layer() == NULL);
+ ASSERT_TRUE(grid.center_layer() == NULL);
+ ASSERT_TRUE(grid.right_layer() == NULL);
+ ASSERT_TRUE(grid.bottom_left_layer() == NULL);
+ ASSERT_TRUE(grid.bottom_layer() == NULL);
+ ASSERT_TRUE(grid.bottom_right_layer() == NULL);
grid.SetImages(NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, image.get(), NULL);
// Now only the bottom edge has a layer.
- ASSERT_TRUE(test_api.top_left_layer() == NULL);
- ASSERT_TRUE(test_api.top_layer() == NULL);
- ASSERT_TRUE(test_api.top_right_layer() == NULL);
- ASSERT_TRUE(test_api.left_layer() == NULL);
- ASSERT_TRUE(test_api.center_layer() == NULL);
- ASSERT_TRUE(test_api.right_layer() == NULL);
- ASSERT_TRUE(test_api.bottom_left_layer() == NULL);
- ASSERT_FALSE(test_api.bottom_layer() == NULL);
- ASSERT_TRUE(test_api.bottom_right_layer() == NULL);
+ ASSERT_TRUE(grid.top_left_layer() == NULL);
+ ASSERT_TRUE(grid.top_layer() == NULL);
+ ASSERT_TRUE(grid.top_right_layer() == NULL);
+ ASSERT_TRUE(grid.left_layer() == NULL);
+ ASSERT_TRUE(grid.center_layer() == NULL);
+ ASSERT_TRUE(grid.right_layer() == NULL);
+ ASSERT_TRUE(grid.bottom_left_layer() == NULL);
+ ASSERT_FALSE(grid.bottom_layer() == NULL);
+ ASSERT_TRUE(grid.bottom_right_layer() == NULL);
}
// Test that side (top, left, right, bottom) layers that are narrower than their
@@ -217,14 +248,14 @@ TEST_F(ImageGridTest, SmallerSides) {
EXPECT_EQ(gfx::Rect(
kCorner, 0, kSize.width() - 2 * kCorner, kEdge).ToString(),
test_api.GetTransformedLayerBounds(
- *test_api.top_layer()).ToString());
+ *grid.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(
0, kCorner, kEdge, kSize.height() - kCorner).ToString(),
test_api.GetTransformedLayerBounds(
- *test_api.left_layer()).ToString());
+ *grid.left_layer()).ToString());
// The right layer should be flush with the right edge and stretched
// vertically between the top right corner and the bottom.
@@ -232,7 +263,7 @@ TEST_F(ImageGridTest, SmallerSides) {
kSize.width() - kEdge, kCorner,
kEdge, kSize.height() - kCorner).ToString(),
test_api.GetTransformedLayerBounds(
- *test_api.right_layer()).ToString());
+ *grid.right_layer()).ToString());
}
// Test that we hide or clip layers as needed when the grid is assigned a small
@@ -268,11 +299,11 @@ TEST_F(ImageGridTest, TooSmall) {
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());
+ EXPECT_FALSE(grid.top_layer()->visible());
+ EXPECT_FALSE(grid.bottom_layer()->visible());
+ EXPECT_FALSE(grid.left_layer()->visible());
+ EXPECT_FALSE(grid.right_layer()->visible());
+ EXPECT_FALSE(grid.center_layer()->visible());
// The corner images' clip rects should sum to the expected size.
EXPECT_EQ(kSmallSize.width(),
@@ -294,11 +325,11 @@ TEST_F(ImageGridTest, TooSmall) {
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());
+ EXPECT_TRUE(grid.top_layer()->visible());
+ EXPECT_TRUE(grid.bottom_layer()->visible());
+ EXPECT_TRUE(grid.left_layer()->visible());
+ EXPECT_TRUE(grid.right_layer()->visible());
+ EXPECT_TRUE(grid.center_layer()->visible());
// We shouldn't be clipping the corner images anymore.
EXPECT_TRUE(test_api.top_left_clip_rect().IsEmpty());
diff --git a/ash/wm/resize_shadow.cc b/ash/wm/resize_shadow.cc
index 983fdfb..5807700 100644
--- a/ash/wm/resize_shadow.cc
+++ b/ash/wm/resize_shadow.cc
@@ -4,167 +4,106 @@
#include "ash/wm/resize_shadow.h"
+#include "ash/wm/image_grid.h"
+#include "base/time.h"
#include "grit/ui_resources.h"
-#include "third_party/skia/include/core/SkColor.h"
#include "ui/aura/window.h"
-#include "ui/base/animation/slide_animation.h"
#include "ui/base/hit_test.h"
+#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/compositor/layer.h"
#include "ui/gfx/compositor/scoped_layer_animation_settings.h"
namespace {
-// Height or width for the resize border shadow.
-const int kShadowSize = 6;
-// Amount to inset the resize effect from the window corners.
-const int kShadowInset = 4;
-// Color for resize effect.
-const SkColor kShadowLayerColor = SkColorSetRGB(0, 0, 0);
// Final opacity for resize effect.
-const int kShadowTargetOpacity = 64;
+const float kShadowTargetOpacity = 0.25f;
// Animation time for resize effect in milliseconds.
-const int kShadowSlideDurationMs = 200;
+const int kShadowAnimationDurationMs = 200;
+
+// Sets up a layer as invisible and fully transparent, without animating.
+void InitLayer(ui::Layer* layer) {
+ layer->SetVisible(false);
+ layer->SetOpacity(0.f);
+}
+
+// Triggers an opacity animation that will make |layer| become |visible|.
+void ShowLayer(ui::Layer* layer, bool visible) {
+ ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
+ settings.SetTransitionDuration(
+ base::TimeDelta::FromMilliseconds(kShadowAnimationDurationMs));
+ layer->SetOpacity(visible ? kShadowTargetOpacity : 0.f);
+ // Sets the layer visibility after a delay, which will be identical to the
+ // opacity animation duration.
+ layer->SetVisible(visible);
+}
} // namespace
namespace ash {
namespace internal {
-ResizeShadow::ResizeShadow() {}
+ResizeShadow::ResizeShadow() : last_hit_test_(HTNOWHERE) {}
ResizeShadow::~ResizeShadow() {}
void ResizeShadow::Init(aura::Window* window) {
- ui::Layer* parent = window->layer();
- InitLayer(parent, &top_layer_);
- InitLayer(parent, &left_layer_);
- InitLayer(parent, &right_layer_);
- InitLayer(parent, &bottom_layer_);
- InitAnimation(&top_animation_);
- InitAnimation(&left_animation_);
- InitAnimation(&right_animation_);
- InitAnimation(&bottom_animation_);
+ // Set up our image grid and images.
+ ResourceBundle& res = ResourceBundle::GetSharedInstance();
+ image_grid_.reset(new ImageGrid());
+ image_grid_->SetImages(
+ &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_TOP_LEFT),
+ &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_TOP),
+ &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_TOP_RIGHT),
+ &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_LEFT),
+ NULL,
+ &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_RIGHT),
+ &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_BOTTOM_LEFT),
+ &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_BOTTOM),
+ &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_BOTTOM_RIGHT));
+ // Initialize all layers to invisible/transparent.
+ InitLayer(image_grid_->top_left_layer());
+ InitLayer(image_grid_->top_layer());
+ InitLayer(image_grid_->top_right_layer());
+ InitLayer(image_grid_->left_layer());
+ InitLayer(image_grid_->right_layer());
+ InitLayer(image_grid_->bottom_left_layer());
+ InitLayer(image_grid_->bottom_layer());
+ InitLayer(image_grid_->bottom_right_layer());
+ // Add image grid as a child of the window's layer so it follows the window
+ // as it moves.
+ window->layer()->Add(image_grid_->layer());
}
-void ResizeShadow::ShowForHitTest(int hit_test) {
- // TODO(jamescook): Add support for top_left, top_right, bottom_left, and
- // bottom_right corners. This approach matches the mocks but looks a little
- // funny.
- bool top = false;
- bool left = false;
- bool right = false;
- bool bottom = false;
- switch (hit_test) {
- case HTTOPLEFT:
- top = true;
- left = true;
- break;
- case HTTOP:
- top = true;
- break;
- case HTTOPRIGHT:
- top = true;
- right = true;
- break;
- case HTLEFT:
- left = true;
- break;
- case HTRIGHT:
- right = true;
- break;
- case HTBOTTOMLEFT:
- left = true;
- bottom = true;
- break;
- case HTBOTTOM:
- bottom = true;
- break;
- case HTBOTTOMRIGHT:
- bottom = true;
- right = true;
- break;
- default:
- break;
- }
- if (top)
- top_animation_->Show();
- else
- top_animation_->Hide();
- if (left)
- left_animation_->Show();
- else
- left_animation_->Hide();
- if (right)
- right_animation_->Show();
- else
- right_animation_->Hide();
- if (bottom)
- bottom_animation_->Show();
- else
- bottom_animation_->Hide();
+void ResizeShadow::ShowForHitTest(int hit) {
+ // Don't start animations unless something changed.
+ if (hit == last_hit_test_)
+ return;
+ last_hit_test_ = hit;
+
+ // Show affected corners.
+ ShowLayer(image_grid_->top_left_layer(), hit == HTTOPLEFT);
+ ShowLayer(image_grid_->top_right_layer(), hit == HTTOPRIGHT);
+ ShowLayer(image_grid_->bottom_left_layer(), hit == HTBOTTOMLEFT);
+ ShowLayer(image_grid_->bottom_right_layer(), hit == HTBOTTOMRIGHT);
+
+ // Show affected edges.
+ ShowLayer(image_grid_->top_layer(),
+ hit == HTTOPLEFT || hit == HTTOP || hit == HTTOPRIGHT);
+ ShowLayer(image_grid_->left_layer(),
+ hit == HTTOPLEFT || hit == HTLEFT || hit == HTBOTTOMLEFT);
+ ShowLayer(image_grid_->right_layer(),
+ hit == HTTOPRIGHT || hit == HTRIGHT || hit == HTBOTTOMRIGHT);
+ ShowLayer(image_grid_->bottom_layer(),
+ hit == HTBOTTOMLEFT || hit == HTBOTTOM || hit == HTBOTTOMRIGHT);
}
void ResizeShadow::Hide() {
- // Small optimization since we frequently invoke Hide().
- if (top_animation_->IsShowing() ||
- left_animation_->IsShowing() ||
- right_animation_->IsShowing() ||
- bottom_animation_->IsShowing())
- ShowForHitTest(HTNOWHERE);
-}
-
-void ResizeShadow::Layout(const gfx::Rect& bounds) {
- // Position the resize border effects near the window edges.
- top_layer_->SetBounds(gfx::Rect(kShadowInset,
- -kShadowSize,
- bounds.width() - 2 * kShadowInset,
- kShadowSize));
- bottom_layer_->SetBounds(gfx::Rect(kShadowInset,
- bounds.height(),
- bounds.width() - 2 * kShadowInset,
- kShadowSize));
- left_layer_->SetBounds(gfx::Rect(-kShadowSize,
- kShadowInset,
- kShadowSize,
- bounds.height() - 2 * kShadowInset));
- right_layer_->SetBounds(gfx::Rect(bounds.width(),
- kShadowInset,
- kShadowSize,
- bounds.height() - 2 * kShadowInset));
-}
-
-void ResizeShadow::AnimationProgressed(const ui::Animation* animation) {
- int opacity = animation->CurrentValueBetween(0, kShadowTargetOpacity);
- if (animation == top_animation_.get())
- UpdateLayerOpacity(top_layer_.get(), opacity);
- else if (animation == left_animation_.get())
- UpdateLayerOpacity(left_layer_.get(), opacity);
- else if (animation == right_animation_.get())
- UpdateLayerOpacity(right_layer_.get(), opacity);
- else if (animation == bottom_animation_.get())
- UpdateLayerOpacity(bottom_layer_.get(), opacity);
-}
-
-void ResizeShadow::InitLayer(ui::Layer* parent,
- scoped_ptr<ui::Layer>* new_layer) {
- // Use solid colors because they don't require video memory.
- new_layer->reset(new ui::Layer(ui::Layer::LAYER_SOLID_COLOR));
- // Transparency must be part of the color for solid color layers.
- // Start fully transparent so we can smoothly animate in.
- new_layer->get()->SetColor(SkColorSetARGB(0, 0, 0, 0));
- new_layer->get()->SetVisible(false);
- parent->Add(new_layer->get());
-}
-
-void ResizeShadow::InitAnimation(scoped_ptr<ui::SlideAnimation>* animation) {
- animation->reset(new ui::SlideAnimation(this));
- animation->get()->SetSlideDuration(kShadowSlideDurationMs);
+ ShowForHitTest(HTNOWHERE);
}
-void ResizeShadow::UpdateLayerOpacity(ui::Layer* layer, int opacity) {
- SkColor color = SkColorSetA(kShadowLayerColor, opacity);
- layer->SetColor(color);
- layer->SetVisible(opacity != 0);
+void ResizeShadow::Layout(const gfx::Rect& content_bounds) {
+ gfx::Rect local_bounds(content_bounds.size());
+ image_grid_->SetContentBounds(local_bounds);
}
} // namespace internal
diff --git a/ash/wm/resize_shadow.h b/ash/wm/resize_shadow.h
index b0307fa..0961607 100644
--- a/ash/wm/resize_shadow.h
+++ b/ash/wm/resize_shadow.h
@@ -8,7 +8,6 @@
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
-#include "ui/base/animation/animation_delegate.h"
namespace aura {
class Window;
@@ -18,19 +17,20 @@ class Rect;
}
namespace ui {
class Layer;
-class SlideAnimation;
}
namespace ash {
namespace internal {
+class ImageGrid;
+
// A class to render the resize edge effect when the user moves their mouse
// over a sizing edge. This is just a visual effect; the actual resize is
// handled by the EventFilter.
-class ResizeShadow : public ui::AnimationDelegate {
+class ResizeShadow {
public:
ResizeShadow();
- virtual ~ResizeShadow();
+ ~ResizeShadow();
// Initializes the resize effect layers for a given |window|.
void Init(aura::Window* window);
@@ -42,34 +42,16 @@ class ResizeShadow : public ui::AnimationDelegate {
// Hides all resize effects.
void Hide();
- // Updates the effect positions based on the |bounds| of its parent.
+ // Updates the effect positions based on the |bounds| of the window.
void Layout(const gfx::Rect& bounds);
- // ui::AnimationDelegate overrides:
- virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE;
-
private:
- void InitLayer(ui::Layer* parent, scoped_ptr<ui::Layer>* new_layer);
-
- void InitAnimation(scoped_ptr<ui::SlideAnimation>* animation);
-
- // Update the |opacity| for |layer| and sets the layer invisible if it is
- // completely transparent.
- void UpdateLayerOpacity(ui::Layer* layer, int opacity);
-
- // Layers of type LAYER_SOLID_COLOR for efficiency.
- scoped_ptr<ui::Layer> top_layer_;
- scoped_ptr<ui::Layer> left_layer_;
- scoped_ptr<ui::Layer> right_layer_;
- scoped_ptr<ui::Layer> bottom_layer_;
+ // Images for the shadow effect.
+ scoped_ptr<ImageGrid> image_grid_;
- // Slide animations for layer opacity.
- // TODO(jamescook): Switch to using ui::ScopedLayerAnimationSettings once
- // solid color layers support that for opacity.
- scoped_ptr<ui::SlideAnimation> top_animation_;
- scoped_ptr<ui::SlideAnimation> left_animation_;
- scoped_ptr<ui::SlideAnimation> right_animation_;
- scoped_ptr<ui::SlideAnimation> bottom_animation_;
+ // Hit test value from last call to ShowForHitTest(). Used to prevent
+ // repeatedly triggering the same animations for the same hit.
+ int last_hit_test_;
DISALLOW_COPY_AND_ASSIGN(ResizeShadow);
};
diff --git a/ash/wm/shadow.cc b/ash/wm/shadow.cc
index c6fbd44a..d763bc7 100644
--- a/ash/wm/shadow.cc
+++ b/ash/wm/shadow.cc
@@ -38,7 +38,7 @@ float GetOpacityForStyle(ash::internal::Shadow::Style style) {
namespace ash {
namespace internal {
-Shadow::Shadow() {
+Shadow::Shadow() : style_(STYLE_ACTIVE) {
}
Shadow::~Shadow() {
@@ -167,18 +167,8 @@ void Shadow::UpdateImagesForStyle() {
}
void Shadow::UpdateImageGridBounds() {
- image_grid_->SetSize(
- gfx::Size(content_bounds_.width() +
- image_grid_->left_image_width() +
- image_grid_->right_image_width(),
- content_bounds_.height() +
- image_grid_->top_image_height() +
- image_grid_->bottom_image_height()));
- image_grid_->layer()->SetBounds(
- gfx::Rect(content_bounds_.x() - image_grid_->left_image_width(),
- content_bounds_.y() - image_grid_->top_image_height(),
- image_grid_->layer()->bounds().width(),
- image_grid_->layer()->bounds().height()));
+ // Update bounds based on content bounds and image sizes.
+ image_grid_->SetContentBounds(content_bounds_);
}
} // namespace internal
diff --git a/ui/resources/ui_resources.grd b/ui/resources/ui_resources.grd
index 6f89ae5..a0a8fd2 100644
--- a/ui/resources/ui_resources.grd
+++ b/ui/resources/ui_resources.grd
@@ -150,6 +150,14 @@
<include name="IDR_AURA_LAUNCHER_OVERFLOW_PUSHED" file="aura/launcher_overflow_p.png" type="BINDATA" />
<include name="IDR_AURA_MULTI_WINDOW_RESIZE_H" file="aura/multi_window_resize_h.png" type="BINDATA" />
<include name="IDR_AURA_MULTI_WINDOW_RESIZE_V" file="aura/multi_window_resize_v.png" type="BINDATA" />
+ <include name="IDR_AURA_RESIZE_SHADOW_TOP_LEFT" file="aura/resize_shadow_top_left.png" type="BINDATA" />
+ <include name="IDR_AURA_RESIZE_SHADOW_TOP" file="aura/resize_shadow_top.png" type="BINDATA" />
+ <include name="IDR_AURA_RESIZE_SHADOW_TOP_RIGHT" file="aura/resize_shadow_top_right.png" type="BINDATA" />
+ <include name="IDR_AURA_RESIZE_SHADOW_LEFT" file="aura/resize_shadow_left.png" type="BINDATA" />
+ <include name="IDR_AURA_RESIZE_SHADOW_RIGHT" file="aura/resize_shadow_right.png" type="BINDATA" />
+ <include name="IDR_AURA_RESIZE_SHADOW_BOTTOM_LEFT" file="aura/resize_shadow_bottom_left.png" type="BINDATA" />
+ <include name="IDR_AURA_RESIZE_SHADOW_BOTTOM" file="aura/resize_shadow_bottom.png" type="BINDATA" />
+ <include name="IDR_AURA_RESIZE_SHADOW_BOTTOM_RIGHT" file="aura/resize_shadow_bottom_right.png" type="BINDATA" />
<include name="IDR_AURA_SHADOW_ACTIVE_TOP_LEFT" file="aura/window_shadow_active_top_left.png" type="BINDATA" />
<include name="IDR_AURA_SHADOW_ACTIVE_TOP" file="aura/window_shadow_active_top.png" type="BINDATA" />
<include name="IDR_AURA_SHADOW_ACTIVE_TOP_RIGHT" file="aura/window_shadow_active_top_right.png" type="BINDATA" />