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/drag_window_controller.h" 6 7 #include "ash/shell_window_ids.h" 8 #include "ash/wm/window_util.h" 9 #include "ui/aura/client/screen_position_client.h" 10 #include "ui/aura/root_window.h" 11 #include "ui/aura/window.h" 12 #include "ui/compositor/layer.h" 13 #include "ui/compositor/scoped_layer_animation_settings.h" 14 #include "ui/views/corewm/shadow_types.h" 15 #include "ui/views/corewm/window_util.h" 16 #include "ui/views/view.h" 17 #include "ui/views/widget/widget.h" 18 19 namespace ash { 20 namespace internal { 21 DragWindowController(aura::Window * window)22DragWindowController::DragWindowController(aura::Window* window) 23 : window_(window), 24 drag_widget_(NULL), 25 layer_(NULL) { 26 } 27 ~DragWindowController()28DragWindowController::~DragWindowController() { 29 Hide(); 30 } 31 SetDestinationDisplay(const gfx::Display & dst_display)32void DragWindowController::SetDestinationDisplay( 33 const gfx::Display& dst_display) { 34 dst_display_ = dst_display; 35 } 36 Show()37void DragWindowController::Show() { 38 if (!drag_widget_) 39 CreateDragWidget(window_->GetBoundsInScreen()); 40 drag_widget_->Show(); 41 } 42 SetBounds(const gfx::Rect & bounds)43void DragWindowController::SetBounds(const gfx::Rect& bounds) { 44 DCHECK(drag_widget_); 45 bounds_ = bounds; 46 SetBoundsInternal(bounds); 47 } 48 Hide()49void DragWindowController::Hide() { 50 if (drag_widget_) { 51 drag_widget_->Close(); 52 drag_widget_ = NULL; 53 } 54 if (layer_) { 55 views::corewm::DeepDeleteLayers(layer_); 56 layer_ = NULL; 57 } 58 } 59 SetOpacity(float opacity)60void DragWindowController::SetOpacity(float opacity) { 61 DCHECK(drag_widget_); 62 ui::Layer* layer = drag_widget_->GetNativeWindow()->layer(); 63 ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator()); 64 layer->SetOpacity(opacity); 65 } 66 CreateDragWidget(const gfx::Rect & bounds)67void DragWindowController::CreateDragWidget(const gfx::Rect& bounds) { 68 DCHECK(!drag_widget_); 69 drag_widget_ = new views::Widget; 70 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); 71 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 72 params.parent = window_->parent(); 73 params.can_activate = false; 74 params.keep_on_top = true; 75 drag_widget_->set_focus_on_creation(false); 76 drag_widget_->Init(params); 77 drag_widget_->SetVisibilityChangedAnimationsEnabled(false); 78 drag_widget_->GetNativeWindow()->SetName("DragWindow"); 79 drag_widget_->GetNativeWindow()->set_id(kShellWindowId_PhantomWindow); 80 // Show shadow for the dragging window. 81 SetShadowType(drag_widget_->GetNativeWindow(), 82 views::corewm::SHADOW_TYPE_RECTANGULAR); 83 SetBoundsInternal(bounds); 84 drag_widget_->StackAbove(window_); 85 86 RecreateWindowLayers(); 87 aura::Window* window = drag_widget_->GetNativeWindow(); 88 layer_->SetVisible(true); 89 window->layer()->Add(layer_); 90 window->layer()->StackAtTop(layer_); 91 92 // Show the widget after all the setups. 93 drag_widget_->Show(); 94 95 // Fade the window in. 96 ui::Layer* widget_layer = drag_widget_->GetNativeWindow()->layer(); 97 widget_layer->SetOpacity(0); 98 ui::ScopedLayerAnimationSettings scoped_setter(widget_layer->GetAnimator()); 99 widget_layer->SetOpacity(1); 100 } 101 SetBoundsInternal(const gfx::Rect & bounds)102void DragWindowController::SetBoundsInternal(const gfx::Rect& bounds) { 103 aura::Window* window = drag_widget_->GetNativeWindow(); 104 aura::client::ScreenPositionClient* screen_position_client = 105 aura::client::GetScreenPositionClient(window->GetRootWindow()); 106 if (screen_position_client && dst_display_.is_valid()) 107 screen_position_client->SetBounds(window, bounds, dst_display_); 108 else 109 drag_widget_->SetBounds(bounds); 110 } 111 RecreateWindowLayers()112void DragWindowController::RecreateWindowLayers() { 113 DCHECK(!layer_); 114 layer_ = views::corewm::RecreateWindowLayers(window_, true); 115 layer_->set_delegate(window_->layer()->delegate()); 116 // Place the layer at (0, 0) of the DragWindowController's window. 117 gfx::Rect layer_bounds = layer_->bounds(); 118 layer_bounds.set_origin(gfx::Point(0, 0)); 119 layer_->SetBounds(layer_bounds); 120 layer_->SetVisible(false); 121 // Detach it from the current container. 122 layer_->parent()->Remove(layer_); 123 } 124 125 } // namespace internal 126 } // namespace ash 127