OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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 "ui/aura_shell/transient_container_layout_manager.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "ui/aura/client/aura_constants.h" |
| 9 #include "ui/aura/desktop.h" |
| 10 #include "ui/aura/event.h" |
| 11 #include "ui/aura/window.h" |
| 12 #include "ui/aura_shell/shell.h" |
| 13 #include "ui/aura_shell/stacking_controller.h" |
| 14 #include "ui/gfx/canvas.h" |
| 15 #include "ui/gfx/compositor/layer.h" |
| 16 #include "ui/gfx/compositor/layer_animator.h" |
| 17 #include "views/view.h" |
| 18 #include "views/widget/widget.h" |
| 19 |
| 20 namespace aura_shell { |
| 21 namespace internal { |
| 22 |
| 23 namespace { |
| 24 |
| 25 class ScreenView : public views::View { |
| 26 public: |
| 27 ScreenView() {} |
| 28 virtual ~ScreenView() {} |
| 29 |
| 30 // Overridden from views::View: |
| 31 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { |
| 32 canvas->FillRect(SK_ColorBLACK, GetLocalBounds()); |
| 33 } |
| 34 |
| 35 private: |
| 36 DISALLOW_COPY_AND_ASSIGN(ScreenView); |
| 37 }; |
| 38 |
| 39 } // namespace |
| 40 |
| 41 //////////////////////////////////////////////////////////////////////////////// |
| 42 // TransientContainerLayoutManager, public: |
| 43 |
| 44 TransientContainerLayoutManager::TransientContainerLayoutManager( |
| 45 aura::Window* container) |
| 46 : container_(container), |
| 47 modal_screen_(NULL), |
| 48 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 49 modality_filter_(new ModalityEventFilter(container, this))) { |
| 50 } |
| 51 |
| 52 TransientContainerLayoutManager::~TransientContainerLayoutManager() { |
| 53 } |
| 54 |
| 55 //////////////////////////////////////////////////////////////////////////////// |
| 56 // TransientContainerLayoutManager, aura::LayoutManager implementation: |
| 57 |
| 58 void TransientContainerLayoutManager::OnWindowResized() { |
| 59 if (modal_screen_) { |
| 60 modal_screen_->SetBounds(gfx::Rect(0, 0, container_->bounds().width(), |
| 61 container_->bounds().height())); |
| 62 } |
| 63 } |
| 64 |
| 65 void TransientContainerLayoutManager::OnWindowAddedToLayout( |
| 66 aura::Window* child) { |
| 67 child->AddObserver(this); |
| 68 } |
| 69 |
| 70 void TransientContainerLayoutManager::OnWillRemoveWindowFromLayout( |
| 71 aura::Window* child) { |
| 72 child->RemoveObserver(this); |
| 73 if (child->GetBoolProperty(aura::kModalKey)) |
| 74 RemoveModalWindow(child); |
| 75 } |
| 76 |
| 77 void TransientContainerLayoutManager::OnChildWindowVisibilityChanged( |
| 78 aura::Window* child, |
| 79 bool visible) { |
| 80 } |
| 81 |
| 82 void TransientContainerLayoutManager::SetChildBounds( |
| 83 aura::Window* child, |
| 84 const gfx::Rect& requested_bounds) { |
| 85 SetChildBoundsDirect(child, requested_bounds); |
| 86 } |
| 87 |
| 88 //////////////////////////////////////////////////////////////////////////////// |
| 89 // TransientContainerLayoutManager, aura::WindowObserver implementation: |
| 90 |
| 91 void TransientContainerLayoutManager::OnPropertyChanged(aura::Window* window, |
| 92 const char* key, |
| 93 void* old) { |
| 94 if (key != aura::kModalKey) |
| 95 return; |
| 96 |
| 97 if (window->GetBoolProperty(aura::kModalKey)) { |
| 98 AddModalWindow(window); |
| 99 } else if (reinterpret_cast<bool>(old)) { |
| 100 RemoveModalWindow(window); |
| 101 } |
| 102 } |
| 103 |
| 104 //////////////////////////////////////////////////////////////////////////////// |
| 105 // TransientContainerLayoutManager, ui::LayerAnimationObserver implementation: |
| 106 |
| 107 void TransientContainerLayoutManager::OnLayerAnimationEnded( |
| 108 const ui::LayerAnimationSequence* sequence) { |
| 109 if (modal_screen_ && !modal_screen_->GetNativeView()->layer()->ShouldDraw()) |
| 110 DestroyModalScreen(); |
| 111 } |
| 112 |
| 113 void TransientContainerLayoutManager::OnLayerAnimationAborted( |
| 114 const ui::LayerAnimationSequence* sequence) { |
| 115 } |
| 116 |
| 117 void TransientContainerLayoutManager::OnLayerAnimationScheduled( |
| 118 const ui::LayerAnimationSequence* sequence) { |
| 119 } |
| 120 |
| 121 //////////////////////////////////////////////////////////////////////////////// |
| 122 // TransientContainerLayoutManager, |
| 123 // ModalityEventFilter::Delegate implementation: |
| 124 |
| 125 bool TransientContainerLayoutManager::CanWindowReceiveEvents( |
| 126 aura::Window* window) { |
| 127 return StackingController::GetActivatableWindow(window) == modal_window(); |
| 128 } |
| 129 |
| 130 //////////////////////////////////////////////////////////////////////////////// |
| 131 // TransientContainerLayoutManager, private: |
| 132 |
| 133 void TransientContainerLayoutManager::AddModalWindow(aura::Window* window) { |
| 134 modal_windows_.push_back(window); |
| 135 CreateModalScreen(); |
| 136 container_->MoveChildToFront(window); |
| 137 window->Activate(); |
| 138 } |
| 139 |
| 140 void TransientContainerLayoutManager::RemoveModalWindow(aura::Window* window) { |
| 141 aura::Window::Windows::iterator it = |
| 142 std::find(modal_windows_.begin(), modal_windows_.end(), window); |
| 143 if (it != modal_windows_.end()) |
| 144 modal_windows_.erase(it); |
| 145 |
| 146 if (modal_windows_.empty()) |
| 147 HideModalScreen(); |
| 148 else |
| 149 modal_window()->Activate(); |
| 150 } |
| 151 |
| 152 void TransientContainerLayoutManager::CreateModalScreen() { |
| 153 if (modal_screen_) |
| 154 return; |
| 155 modal_screen_ = new views::Widget; |
| 156 views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL); |
| 157 params.parent = container_; |
| 158 params.bounds = gfx::Rect(0, 0, container_->bounds().width(), |
| 159 container_->bounds().height()); |
| 160 modal_screen_->Init(params); |
| 161 modal_screen_->GetNativeView()->set_name( |
| 162 "TransientContainerLayoutManager.ModalScreen"); |
| 163 modal_screen_->SetContentsView(new ScreenView); |
| 164 modal_screen_->GetNativeView()->layer()->SetOpacity(0.0f); |
| 165 modal_screen_->GetNativeView()->layer()->GetAnimator()->AddObserver(this); |
| 166 |
| 167 Shell::GetInstance()->AddDesktopEventFilter(modality_filter_.get()); |
| 168 |
| 169 ui::LayerAnimator::ScopedSettings settings( |
| 170 modal_screen_->GetNativeView()->layer()->GetAnimator()); |
| 171 modal_screen_->Show(); |
| 172 modal_screen_->GetNativeView()->layer()->SetOpacity(0.5f); |
| 173 container_->MoveChildToFront(modal_screen_->GetNativeView()); |
| 174 } |
| 175 |
| 176 void TransientContainerLayoutManager::DestroyModalScreen() { |
| 177 modal_screen_->GetNativeView()->layer()->GetAnimator()->RemoveObserver(this); |
| 178 modal_screen_->Close(); |
| 179 modal_screen_ = NULL; |
| 180 } |
| 181 |
| 182 void TransientContainerLayoutManager::HideModalScreen() { |
| 183 Shell::GetInstance()->RemoveDesktopEventFilter(modality_filter_.get()); |
| 184 ui::LayerAnimator::ScopedSettings settings( |
| 185 modal_screen_->GetNativeView()->layer()->GetAnimator()); |
| 186 modal_screen_->GetNativeView()->layer()->SetOpacity(0.0f); |
| 187 } |
| 188 |
| 189 } // namespace internal |
| 190 } // namespace aura_shell |
OLD | NEW |