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.
5 #include "ash/wm/resize_shadow.h"
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"
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;
23 // Sets up a layer as invisible and fully transparent, without animating.
24 void InitLayer(ui::Layer
* layer
) {
25 layer
->SetVisible(false);
26 layer
->SetOpacity(0.f
);
29 // Triggers an opacity animation that will make |layer| become |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
);
44 ResizeShadow::ResizeShadow() : last_hit_test_(HTNOWHERE
) {}
46 ResizeShadow::~ResizeShadow() {}
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
),
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
73 window
->layer()->Add(image_grid_
->layer());
76 void ResizeShadow::ShowForHitTest(int hit
) {
77 // Don't start animations unless something changed.
78 if (hit
== last_hit_test_
)
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
);
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
);
99 void ResizeShadow::Hide() {
100 ShowForHitTest(HTNOWHERE
);
103 void ResizeShadow::Layout(const gfx::Rect
& content_bounds
) {
104 gfx::Rect
local_bounds(content_bounds
.size());
105 image_grid_
->SetContentBounds(local_bounds
);