1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// found in the LICENSE file.
4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ash/wm/overview/window_selector_item.h"
60529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ash/screen_util.h"
80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ash/shell.h"
90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ash/shell_window_ids.h"
100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ash/wm/overview/scoped_transform_overview_window.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/wm/overview/transparent_activate_window_button.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/auto_reset.h"
13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "grit/ash_resources.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/aura/window.h"
150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ui/base/resource/resource_bundle.h"
160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ui/compositor/scoped_layer_animation_settings.h"
17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/views/controls/button/image_button.h"
180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ui/views/controls/label.h"
190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ui/views/layout/box_layout.h"
200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ui/views/widget/widget.h"
21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace ash {
23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace {
25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)views::Widget* CreateCloseWindowButton(aura::Window* root_window,
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                       views::ButtonListener* listener) {
28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  views::Widget* widget = new views::Widget;
29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  views::Widget::InitParams params;
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.type = views::Widget::InitParams::TYPE_POPUP;
31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.parent =
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      Shell::GetContainer(root_window, ash::kShellWindowId_OverlayContainer);
35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  widget->set_focus_on_creation(false);
36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  widget->Init(params);
37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  views::ImageButton* button = new views::ImageButton(listener);
38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  button->SetImage(views::CustomButton::STATE_NORMAL,
40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE));
41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  button->SetImage(views::CustomButton::STATE_HOVERED,
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE_H));
43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  button->SetImage(views::CustomButton::STATE_PRESSED,
44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE_P));
45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  widget->SetContentsView(button);
46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  widget->SetSize(rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE)->size());
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  widget->Show();
48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return widget;
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace
52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// In the conceptual overview table, the window margin is the space reserved
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// around the window within the cell. This margin does not overlap so the
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// closest distance between adjacent windows will be twice this amount.
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static const int kWindowMargin = 30;
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Foreground label color.
590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstatic const SkColor kLabelColor = SK_ColorWHITE;
600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Background label color.
620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstatic const SkColor kLabelBackground = SK_ColorTRANSPARENT;
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Label shadow color.
650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstatic const SkColor kLabelShadow = 0xB0000000;
660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Vertical padding for the label, both over and beneath it.
680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstatic const int kVerticalLabelPadding = 20;
690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Solid shadow length from the label
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstatic const int kVerticalShadowOffset = 1;
720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Amount of blur applied to the label shadow
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstatic const int kShadowBlur = 10;
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst int WindowSelectorItem::kFadeInMilliseconds = 80;
770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Opacity for dimmed items.
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const float kDimmedItemOpacity = 0.5f;
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)WindowSelectorItem::WindowSelectorItem()
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : dimmed_(false),
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      root_window_(NULL),
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      in_bounds_update_(false),
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      window_label_view_(NULL) {
86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)WindowSelectorItem::~WindowSelectorItem() {
89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void WindowSelectorItem::RemoveWindow(const aura::Window* window) {
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // If empty WindowSelectorItem will be destroyed immediately after this by
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // its owner.
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (empty())
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_label_.reset();
97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  UpdateWindowLabels(target_bounds_, root_window_, false);
98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  UpdateCloseButtonBounds(root_window_, false);
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void WindowSelectorItem::SetBounds(aura::Window* root_window,
1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                   const gfx::Rect& target_bounds,
1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                   bool animate) {
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (in_bounds_update_)
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::AutoReset<bool> auto_reset_in_bounds_update(&in_bounds_update_, true);
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  root_window_ = root_window;
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  target_bounds_ = target_bounds;
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Set the bounds of the transparent window handler to cover the entire
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // bounding box area.
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!activate_window_button_) {
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    activate_window_button_.reset(
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        new TransparentActivateWindowButton(SelectionWindow()));
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  activate_window_button_->SetBounds(target_bounds);
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  UpdateWindowLabels(target_bounds, root_window, animate);
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  gfx::Rect inset_bounds(target_bounds);
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  inset_bounds.Inset(kWindowMargin, kWindowMargin);
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetItemBounds(root_window, inset_bounds, animate);
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  UpdateCloseButtonBounds(root_window, animate);
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowSelectorItem::RecomputeWindowTransforms() {
1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (in_bounds_update_ || target_bounds_.IsEmpty())
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(root_window_);
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::AutoReset<bool> auto_reset_in_bounds_update(&in_bounds_update_, true);
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  gfx::Rect inset_bounds(target_bounds_);
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  inset_bounds.Inset(kWindowMargin, kWindowMargin);
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetItemBounds(root_window_, inset_bounds, false);
134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  UpdateCloseButtonBounds(root_window_, false);
135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void WindowSelectorItem::SendFocusAlert() const {
13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  activate_window_button_->SendFocusAlert();
13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WindowSelectorItem::SetDimmed(bool dimmed) {
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  dimmed_ = dimmed;
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SetOpacity(dimmed ? kDimmedItemOpacity : 1.0f);
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void WindowSelectorItem::ButtonPressed(views::Button* sender,
147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                       const ui::Event& event) {
148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  views::Widget::GetWidgetForNativeView(SelectionWindow())->Close();
149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WindowSelectorItem::OnWindowTitleChanged(aura::Window* window) {
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(flackr): Maybe add the new title to a vector of titles so that we can
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // filter any of the titles the window had while in the overview session.
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (window == SelectionWindow())
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    window_label_view_->SetText(window->title());
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void WindowSelectorItem::UpdateCloseButtonBounds(aura::Window* root_window,
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                 bool animate) {
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::RectF align_bounds(SelectionWindow()->layer()->bounds());
161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gfx::Transform window_transform;
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_transform.Translate(align_bounds.x(), align_bounds.y());
163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_transform.PreconcatTransform(SelectionWindow()->layer()->
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                          GetTargetTransform());
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_transform.Translate(-align_bounds.x(), -align_bounds.y());
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_transform.TransformRect(&align_bounds);
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gfx::Rect target_bounds = ToEnclosingRect(align_bounds);
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gfx::Transform close_button_transform;
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  close_button_transform.Translate(target_bounds.right(), target_bounds.y());
171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // If the root window has changed, force the close button to be recreated
173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // and faded in on the new root window.
174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (close_button_ &&
175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      close_button_->GetNativeWindow()->GetRootWindow() != root_window) {
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    close_button_.reset();
177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!close_button_) {
180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    close_button_.reset(CreateCloseWindowButton(root_window, this));
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    gfx::Rect close_button_rect(close_button_->GetNativeWindow()->bounds());
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Align the center of the button with position (0, 0) so that the
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // translate transform does not need to take the button dimensions into
184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // account.
185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    close_button_rect.set_x(-close_button_rect.width() / 2);
186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    close_button_rect.set_y(-close_button_rect.height() / 2);
187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    close_button_->GetNativeWindow()->SetBounds(close_button_rect);
188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    close_button_->GetNativeWindow()->SetTransform(close_button_transform);
189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // The close button is initialized when entering overview, fade the button
190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // in after the window should be in place.
191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ui::Layer* layer = close_button_->GetNativeWindow()->layer();
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    layer->SetOpacity(0);
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    layer->GetAnimator()->StopAnimating();
194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    layer->GetAnimator()->SchedulePauseForProperties(
195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::TimeDelta::FromMilliseconds(
196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            ScopedTransformOverviewWindow::kTransitionMilliseconds),
197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        ui::LayerAnimationElement::OPACITY);
198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    {
199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      settings.SetPreemptionStrategy(
201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          WindowSelectorItem::kFadeInMilliseconds));
204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      layer->SetOpacity(1);
205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  } else {
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (animate) {
208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ui::ScopedLayerAnimationSettings settings(
209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          close_button_->GetNativeWindow()->layer()->GetAnimator());
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      settings.SetPreemptionStrategy(
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          ScopedTransformOverviewWindow::kTransitionMilliseconds));
214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      close_button_->GetNativeWindow()->SetTransform(close_button_transform);
215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    } else {
216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      close_button_->GetNativeWindow()->SetTransform(close_button_transform);
217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WindowSelectorItem::SetOpacity(float opacity) {
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  window_label_->GetNativeWindow()->layer()->SetOpacity(opacity);
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  close_button_->GetNativeWindow()->layer()->SetOpacity(opacity);
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WindowSelectorItem::UpdateWindowLabels(const gfx::Rect& window_bounds,
2275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                            aura::Window* root_window,
2285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                            bool animate) {
2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  gfx::Rect converted_bounds = ScreenUtil::ConvertRectFromScreen(root_window,
2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                                                 window_bounds);
2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  gfx::Rect label_bounds(converted_bounds.x(),
2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                         converted_bounds.bottom(),
2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                         converted_bounds.width(),
2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                         0);
2350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // If the root window has changed, force the window label to be recreated
2370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // and faded in on the new root window.
2380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (window_label_ &&
2390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      window_label_->GetNativeWindow()->GetRootWindow() != root_window) {
2400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    window_label_.reset();
2410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!window_label_) {
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CreateWindowLabel(SelectionWindow()->title());
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    label_bounds.set_height(window_label_view_->GetPreferredSize().height());
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    label_bounds.set_y(label_bounds.y() - window_label_view_->
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           GetPreferredSize().height());
2480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    window_label_->GetNativeWindow()->SetBounds(label_bounds);
2490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ui::Layer* layer = window_label_->GetNativeWindow()->layer();
2500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    layer->SetOpacity(0);
2520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    layer->GetAnimator()->StopAnimating();
2530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    layer->GetAnimator()->SchedulePauseForProperties(
2550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        base::TimeDelta::FromMilliseconds(
2560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            ScopedTransformOverviewWindow::kTransitionMilliseconds),
2570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        ui::LayerAnimationElement::OPACITY);
2580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
2600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    settings.SetPreemptionStrategy(
2610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
2620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
2630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        kFadeInMilliseconds));
2640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    layer->SetOpacity(1);
2650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  } else {
2660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    label_bounds.set_height(window_label_->
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                GetContentsView()->GetPreferredSize().height());
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    label_bounds.set_y(label_bounds.y() - window_label_->
269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           GetContentsView()->GetPreferredSize().height());
2705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (animate) {
2715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      ui::ScopedLayerAnimationSettings settings(
2725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          window_label_->GetNativeWindow()->layer()->GetAnimator());
2735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      settings.SetPreemptionStrategy(
2745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
2755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
2765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          ScopedTransformOverviewWindow::kTransitionMilliseconds));
2775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      window_label_->GetNativeWindow()->SetBounds(label_bounds);
2785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    } else {
2795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      window_label_->GetNativeWindow()->SetBounds(label_bounds);
2805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
2810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
2830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WindowSelectorItem::CreateWindowLabel(const base::string16& title) {
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  window_label_.reset(new views::Widget);
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  views::Widget::InitParams params;
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  params.type = views::Widget::InitParams::TYPE_POPUP;
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  params.parent =
291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      Shell::GetContainer(root_window_, ash::kShellWindowId_OverlayContainer);
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  params.accept_events = false;
293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  params.visible_on_all_workspaces = true;
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  window_label_->set_focus_on_creation(false);
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  window_label_->Init(params);
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  window_label_view_ = new views::Label;
297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  window_label_view_->SetEnabledColor(kLabelColor);
298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  window_label_view_->SetBackgroundColor(kLabelBackground);
2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  window_label_view_->SetShadows(gfx::ShadowValues(
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      1,
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      gfx::ShadowValue(
3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          gfx::Point(0, kVerticalShadowOffset), kShadowBlur, kLabelShadow)));
303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  window_label_view_->SetFontList(
305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      bundle.GetFontList(ui::ResourceBundle::BoldFont));
306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  window_label_view_->SetText(title);
307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kVertical,
308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                  0,
309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                  kVerticalLabelPadding,
310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                  0);
311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  window_label_view_->SetLayoutManager(layout);
312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  window_label_->SetContentsView(window_label_view_);
313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  window_label_->Show();
314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
316d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}  // namespace ash
317