diff options
author | jamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-19 17:09:20 +0000 |
---|---|---|
committer | jamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-19 17:09:20 +0000 |
commit | dd50857397ddf9b7a99478eeb11260251d9dc66b (patch) | |
tree | ffe8f903a3065bebb694a00485f17a959db6020b /ash/wm/resize_shadow.cc | |
parent | 021f9a401f17234425ae523b0743fedfd1b10b8c (diff) | |
download | chromium_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.cc | 207 |
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 |