• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ash/wm/resize_shadow.h"
6 
7 #include "base/time/time.h"
8 #include "grit/ash_resources.h"
9 #include "ui/aura/window.h"
10 #include "ui/base/hit_test.h"
11 #include "ui/base/resource/resource_bundle.h"
12 #include "ui/compositor/layer.h"
13 #include "ui/compositor/scoped_layer_animation_settings.h"
14 #include "ui/wm/core/image_grid.h"
15 
16 namespace {
17 
18 // Final opacity for resize effect.
19 const float kShadowTargetOpacity = 0.25f;
20 // Animation time for resize effect in milliseconds.
21 const int kShadowAnimationDurationMs = 100;
22 
23 // Sets up a layer as invisible and fully transparent, without animating.
InitLayer(ui::Layer * layer)24 void InitLayer(ui::Layer* layer) {
25   layer->SetVisible(false);
26   layer->SetOpacity(0.f);
27 }
28 
29 // Triggers an opacity animation that will make |layer| become |visible|.
ShowLayer(ui::Layer * layer,bool visible)30 void ShowLayer(ui::Layer* layer, bool visible) {
31   ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
32   settings.SetTransitionDuration(
33       base::TimeDelta::FromMilliseconds(kShadowAnimationDurationMs));
34   layer->SetOpacity(visible ? kShadowTargetOpacity : 0.f);
35   // Sets the layer visibility after a delay, which will be identical to the
36   // opacity animation duration.
37   layer->SetVisible(visible);
38 }
39 
40 }  // namespace
41 
42 namespace ash {
43 
ResizeShadow()44 ResizeShadow::ResizeShadow() : last_hit_test_(HTNOWHERE) {}
45 
~ResizeShadow()46 ResizeShadow::~ResizeShadow() {}
47 
Init(aura::Window * window)48 void ResizeShadow::Init(aura::Window* window) {
49   // Set up our image grid and images.
50   ResourceBundle& res = ResourceBundle::GetSharedInstance();
51   image_grid_.reset(new ::wm::ImageGrid);
52   image_grid_->SetImages(
53       &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_TOP_LEFT),
54       &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_TOP),
55       &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_TOP_RIGHT),
56       &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_LEFT),
57       NULL,
58       &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_RIGHT),
59       &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_BOTTOM_LEFT),
60       &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_BOTTOM),
61       &res.GetImageNamed(IDR_AURA_RESIZE_SHADOW_BOTTOM_RIGHT));
62   // Initialize all layers to invisible/transparent.
63   InitLayer(image_grid_->top_left_layer());
64   InitLayer(image_grid_->top_layer());
65   InitLayer(image_grid_->top_right_layer());
66   InitLayer(image_grid_->left_layer());
67   InitLayer(image_grid_->right_layer());
68   InitLayer(image_grid_->bottom_left_layer());
69   InitLayer(image_grid_->bottom_layer());
70   InitLayer(image_grid_->bottom_right_layer());
71   // Add image grid as a child of the window's layer so it follows the window
72   // as it moves.
73   window->layer()->Add(image_grid_->layer());
74 }
75 
ShowForHitTest(int hit)76 void ResizeShadow::ShowForHitTest(int hit) {
77   // Don't start animations unless something changed.
78   if (hit == last_hit_test_)
79     return;
80   last_hit_test_ = hit;
81 
82   // Show affected corners.
83   ShowLayer(image_grid_->top_left_layer(), hit == HTTOPLEFT);
84   ShowLayer(image_grid_->top_right_layer(), hit == HTTOPRIGHT);
85   ShowLayer(image_grid_->bottom_left_layer(), hit == HTBOTTOMLEFT);
86   ShowLayer(image_grid_->bottom_right_layer(), hit == HTBOTTOMRIGHT);
87 
88   // Show affected edges.
89   ShowLayer(image_grid_->top_layer(),
90             hit == HTTOPLEFT || hit == HTTOP || hit == HTTOPRIGHT);
91   ShowLayer(image_grid_->left_layer(),
92             hit == HTTOPLEFT || hit == HTLEFT || hit == HTBOTTOMLEFT);
93   ShowLayer(image_grid_->right_layer(),
94             hit == HTTOPRIGHT || hit == HTRIGHT || hit == HTBOTTOMRIGHT);
95   ShowLayer(image_grid_->bottom_layer(),
96             hit == HTBOTTOMLEFT || hit == HTBOTTOM || hit == HTBOTTOMRIGHT);
97 }
98 
Hide()99 void ResizeShadow::Hide() {
100   ShowForHitTest(HTNOWHERE);
101 }
102 
Layout(const gfx::Rect & content_bounds)103 void ResizeShadow::Layout(const gfx::Rect& content_bounds) {
104   gfx::Rect local_bounds(content_bounds.size());
105   image_grid_->SetContentBounds(local_bounds);
106 }
107 
108 }  // namespace ash
109