summaryrefslogtreecommitdiffstats
path: root/ash/wm/resize_shadow.cc
diff options
context:
space:
mode:
authorjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-19 17:09:20 +0000
committerjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-19 17:09:20 +0000
commitdd50857397ddf9b7a99478eeb11260251d9dc66b (patch)
treeffe8f903a3065bebb694a00485f17a959db6020b /ash/wm/resize_shadow.cc
parent021f9a401f17234425ae523b0743fedfd1b10b8c (diff)
downloadchromium_src-dd50857397ddf9b7a99478eeb11260251d9dc66b.zip
chromium_src-dd50857397ddf9b7a99478eeb11260251d9dc66b.tar.gz
chromium_src-dd50857397ddf9b7a99478eeb11260251d9dc66b.tar.bz2
Ash: Improved resize border effect
Rewrote the effect to use ImageGrid, which both simplifies the code and allows images to be used to provide nice corners. + Exposed underlying ImageGrid layers so I could animate them + Set effect layers invisible at end of hide animation to conserve render resources BUG=118729 TEST=existing unit tests, move cursor near window edges and watch handles fade in and out TBR=ben@chromium.org for ui/ .grd file Review URL: https://chromiumcodereview.appspot.com/9717022 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@127491 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/wm/resize_shadow.cc')
-rw-r--r--ash/wm/resize_shadow.cc207
1 files changed, 73 insertions, 134 deletions
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