| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/wm/workspace/phantom_window_controller.h" | 5 #include "ash/wm/workspace/phantom_window_controller.h" |
| 6 | 6 |
| 7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
| 8 #include "ash/shell_window_ids.h" | 8 #include "ash/shell_window_ids.h" |
| 9 #include "ash/wm/coordinate_conversion.h" | 9 #include "ash/wm/coordinate_conversion.h" |
| 10 #include "third_party/skia/include/core/SkCanvas.h" | 10 #include "third_party/skia/include/core/SkCanvas.h" |
| 11 #include "ui/aura/client/screen_position_client.h" |
| 12 #include "ui/aura/root_window.h" |
| 11 #include "ui/aura/window.h" | 13 #include "ui/aura/window.h" |
| 14 #include "ui/aura/window_delegate.h" |
| 12 #include "ui/aura/window_observer.h" | 15 #include "ui/aura/window_observer.h" |
| 13 #include "ui/base/animation/slide_animation.h" | 16 #include "ui/base/animation/slide_animation.h" |
| 14 #include "ui/compositor/layer.h" | 17 #include "ui/compositor/layer.h" |
| 15 #include "ui/compositor/scoped_layer_animation_settings.h" | 18 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 16 #include "ui/gfx/canvas.h" | 19 #include "ui/gfx/canvas.h" |
| 20 #include "ui/gfx/screen.h" |
| 17 #include "ui/gfx/skia_util.h" | 21 #include "ui/gfx/skia_util.h" |
| 18 #include "ui/views/painter.h" | 22 #include "ui/views/painter.h" |
| 19 #include "ui/views/view.h" | 23 #include "ui/views/view.h" |
| 20 #include "ui/views/widget/widget.h" | 24 #include "ui/views/widget/widget.h" |
| 21 | 25 |
| 22 namespace ash { | 26 namespace ash { |
| 23 namespace internal { | 27 namespace internal { |
| 24 | 28 |
| 25 namespace { | 29 namespace { |
| 26 | 30 |
| 27 // Amount to inset from the bounds for EdgePainter. | 31 // Amount to inset from the bounds for EdgePainter. |
| 28 const int kInsetSize = 4; | 32 const int kInsetSize = 4; |
| 29 | 33 |
| 30 // Size of the round rect used by EdgePainter. | 34 // Size of the round rect used by EdgePainter. |
| 31 const int kRoundRectSize = 4; | 35 const int kRoundRectSize = 4; |
| 32 | 36 |
| 33 // Paints the background of the phantom window. | 37 // Paints the background of the phantom window for window snapping. |
| 34 class EdgePainter : public views::Painter { | 38 class EdgePainter : public views::Painter { |
| 35 public: | 39 public: |
| 36 EdgePainter() {} | 40 EdgePainter() {} |
| 37 | 41 |
| 38 // views::Painter overrides: | 42 // views::Painter overrides: |
| 39 virtual void Paint(gfx::Canvas* canvas, const gfx::Size& size) OVERRIDE { | 43 virtual void Paint(gfx::Canvas* canvas, const gfx::Size& size) OVERRIDE { |
| 40 int x = kInsetSize; | 44 int x = kInsetSize; |
| 41 int y = kInsetSize; | 45 int y = kInsetSize; |
| 42 int w = size.width() - kInsetSize * 2; | 46 int w = size.width() - kInsetSize * 2; |
| 43 int h = size.height() - kInsetSize * 2; | 47 int h = size.height() - kInsetSize * 2; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 63 paint.setStrokeWidth(SkIntToScalar(2)); | 67 paint.setStrokeWidth(SkIntToScalar(2)); |
| 64 canvas->sk_canvas()->drawRoundRect( | 68 canvas->sk_canvas()->drawRoundRect( |
| 65 gfx::RectToSkRect(gfx::Rect(x, y, w, h)), SkIntToScalar(kRoundRectSize), | 69 gfx::RectToSkRect(gfx::Rect(x, y, w, h)), SkIntToScalar(kRoundRectSize), |
| 66 SkIntToScalar(kRoundRectSize), paint); | 70 SkIntToScalar(kRoundRectSize), paint); |
| 67 } | 71 } |
| 68 | 72 |
| 69 private: | 73 private: |
| 70 DISALLOW_COPY_AND_ASSIGN(EdgePainter); | 74 DISALLOW_COPY_AND_ASSIGN(EdgePainter); |
| 71 }; | 75 }; |
| 72 | 76 |
| 77 // Paints the background of the phantom window for window dragging. |
| 78 class WindowPainter : public views::Painter, |
| 79 public aura::WindowObserver { |
| 80 public: |
| 81 explicit WindowPainter(aura::Window* window) |
| 82 : window_(window) { |
| 83 window_->AddObserver(this); |
| 84 } |
| 85 |
| 86 virtual ~WindowPainter() { |
| 87 if (window_) |
| 88 window_->RemoveObserver(this); |
| 89 } |
| 90 |
| 91 // views::Painter overrides: |
| 92 virtual void Paint(gfx::Canvas* canvas, const gfx::Size& size) OVERRIDE { |
| 93 // TODO(yusukes): Paint child windows of the |window_| correctly. Current |
| 94 // code does not paint e.g. web content area in the window. crbug.com/141766 |
| 95 if (window_ && window_->delegate()) |
| 96 window_->delegate()->OnPaint(canvas); |
| 97 } |
| 98 |
| 99 private: |
| 100 // aura::WindowObserver overrides: |
| 101 virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE { |
| 102 DCHECK_EQ(window_, window); |
| 103 window_ = NULL; |
| 104 } |
| 105 |
| 106 aura::Window* window_; |
| 107 |
| 108 DISALLOW_COPY_AND_ASSIGN(WindowPainter); |
| 109 }; |
| 110 |
| 73 } // namespace | 111 } // namespace |
| 74 | 112 |
| 75 PhantomWindowController::PhantomWindowController(aura::Window* window) | 113 PhantomWindowController::PhantomWindowController(aura::Window* window) |
| 76 : window_(window), | 114 : window_(window), |
| 77 phantom_below_window_(NULL), | 115 phantom_below_window_(NULL), |
| 78 phantom_widget_(NULL) { | 116 phantom_widget_(NULL), |
| 117 style_(STYLE_SHADOW) { |
| 79 } | 118 } |
| 80 | 119 |
| 81 PhantomWindowController::~PhantomWindowController() { | 120 PhantomWindowController::~PhantomWindowController() { |
| 82 Hide(); | 121 Hide(); |
| 83 } | 122 } |
| 84 | 123 |
| 124 void PhantomWindowController::SetDestinationDisplay( |
| 125 const gfx::Display& dst_display) { |
| 126 dst_display_ = dst_display; |
| 127 } |
| 128 |
| 85 void PhantomWindowController::Show(const gfx::Rect& bounds) { | 129 void PhantomWindowController::Show(const gfx::Rect& bounds) { |
| 86 if (bounds == bounds_) | 130 if (bounds == bounds_) |
| 87 return; | 131 return; |
| 88 bounds_ = bounds; | 132 bounds_ = bounds; |
| 89 if (!phantom_widget_) { | 133 if (!phantom_widget_) { |
| 90 // Show the phantom at the bounds of the window. We'll animate to the target | 134 // Show the phantom at the bounds of the window. We'll animate to the target |
| 91 // bounds. | 135 // bounds. |
| 92 start_bounds_ = window_->GetBoundsInScreen(); | 136 start_bounds_ = window_->GetBoundsInScreen(); |
| 93 CreatePhantomWidget(start_bounds_); | 137 CreatePhantomWidget(start_bounds_); |
| 94 } else { | 138 } else { |
| 95 start_bounds_ = phantom_widget_->GetWindowBoundsInScreen(); | 139 start_bounds_ = phantom_widget_->GetWindowBoundsInScreen(); |
| 96 } | 140 } |
| 97 animation_.reset(new ui::SlideAnimation(this)); | 141 animation_.reset(new ui::SlideAnimation(this)); |
| 98 animation_->Show(); | 142 animation_->Show(); |
| 99 } | 143 } |
| 100 | 144 |
| 101 void PhantomWindowController::SetBounds(const gfx::Rect& bounds) { | 145 void PhantomWindowController::SetBounds(const gfx::Rect& bounds) { |
| 102 DCHECK(IsShowing()); | 146 DCHECK(IsShowing()); |
| 103 animation_.reset(); | 147 animation_.reset(); |
| 104 bounds_ = bounds; | 148 bounds_ = bounds; |
| 105 phantom_widget_->SetBounds(bounds_); | 149 SetBoundsInternal(bounds); |
| 106 } | 150 } |
| 107 | 151 |
| 108 void PhantomWindowController::Hide() { | 152 void PhantomWindowController::Hide() { |
| 109 if (phantom_widget_) | 153 if (phantom_widget_) |
| 110 phantom_widget_->Close(); | 154 phantom_widget_->Close(); |
| 111 phantom_widget_ = NULL; | 155 phantom_widget_ = NULL; |
| 112 } | 156 } |
| 113 | 157 |
| 114 bool PhantomWindowController::IsShowing() const { | 158 bool PhantomWindowController::IsShowing() const { |
| 115 return phantom_widget_ != NULL; | 159 return phantom_widget_ != NULL; |
| 116 } | 160 } |
| 117 | 161 |
| 162 void PhantomWindowController::set_style(Style style) { |
| 163 // Cannot change |style_| after the widget is initialized. |
| 164 DCHECK(!phantom_widget_); |
| 165 style_ = style; |
| 166 } |
| 167 |
| 168 void PhantomWindowController::SetOpacity(float opacity) { |
| 169 DCHECK(phantom_widget_); |
| 170 ui::Layer* layer = phantom_widget_->GetNativeWindow()->layer(); |
| 171 ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator()); |
| 172 layer->SetOpacity(opacity); |
| 173 } |
| 174 |
| 175 float PhantomWindowController::GetOpacity() const { |
| 176 DCHECK(phantom_widget_); |
| 177 return phantom_widget_->GetNativeWindow()->layer()->opacity(); |
| 178 } |
| 179 |
| 118 void PhantomWindowController::AnimationProgressed( | 180 void PhantomWindowController::AnimationProgressed( |
| 119 const ui::Animation* animation) { | 181 const ui::Animation* animation) { |
| 120 phantom_widget_->SetBounds( | 182 SetBoundsInternal(animation->CurrentValueBetween(start_bounds_, bounds_)); |
| 121 animation->CurrentValueBetween(start_bounds_, bounds_)); | |
| 122 } | 183 } |
| 123 | 184 |
| 124 void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) { | 185 void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) { |
| 125 DCHECK(!phantom_widget_); | 186 DCHECK(!phantom_widget_); |
| 126 phantom_widget_ = new views::Widget; | 187 phantom_widget_ = new views::Widget; |
| 127 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); | 188 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); |
| 128 params.transparent = true; | 189 params.transparent = true; |
| 129 // PhantomWindowController is used by FrameMaximizeButton to highlight the | 190 // PhantomWindowController is used by FrameMaximizeButton to highlight the |
| 130 // launcher button. Put the phantom in the same window as the launcher so that | 191 // launcher button. Put the phantom in the same window as the launcher so that |
| 131 // the phantom is visible. | 192 // the phantom is visible. |
| 132 params.parent = Shell::GetContainer(wm::GetRootWindowMatching(bounds), | 193 params.parent = Shell::GetContainer(wm::GetRootWindowMatching(bounds), |
| 133 kShellWindowId_LauncherContainer); | 194 kShellWindowId_LauncherContainer); |
| 134 params.can_activate = false; | 195 params.can_activate = false; |
| 135 params.keep_on_top = true; | 196 params.keep_on_top = true; |
| 136 phantom_widget_->set_focus_on_creation(false); | 197 phantom_widget_->set_focus_on_creation(false); |
| 137 phantom_widget_->Init(params); | 198 phantom_widget_->Init(params); |
| 138 phantom_widget_->SetVisibilityChangedAnimationsEnabled(false); | 199 phantom_widget_->SetVisibilityChangedAnimationsEnabled(false); |
| 139 phantom_widget_->GetNativeWindow()->SetName("PhantomWindow"); | 200 phantom_widget_->GetNativeWindow()->SetName("PhantomWindow"); |
| 140 views::View* content_view = new views::View; | 201 views::View* content_view = new views::View; |
| 141 content_view->set_background( | 202 switch (style_) { |
| 142 views::Background::CreateBackgroundPainter(true, new EdgePainter)); | 203 case STYLE_SHADOW: |
| 204 content_view->set_background( |
| 205 views::Background::CreateBackgroundPainter(true, new EdgePainter)); |
| 206 break; |
| 207 case STYLE_WINDOW: |
| 208 content_view->set_background(views::Background::CreateBackgroundPainter( |
| 209 true, new WindowPainter(window_))); |
| 210 break; |
| 211 } |
| 143 phantom_widget_->SetContentsView(content_view); | 212 phantom_widget_->SetContentsView(content_view); |
| 144 phantom_widget_->SetBounds(bounds); | 213 SetBoundsInternal(bounds); |
| 145 if (phantom_below_window_) | 214 if (phantom_below_window_) |
| 146 phantom_widget_->StackBelow(phantom_below_window_); | 215 phantom_widget_->StackBelow(phantom_below_window_); |
| 147 else | 216 else |
| 148 phantom_widget_->StackAbove(window_); | 217 phantom_widget_->StackAbove(window_); |
| 149 phantom_widget_->Show(); | 218 phantom_widget_->Show(); |
| 150 // Fade the window in. | 219 // Fade the window in. |
| 151 ui::Layer* layer = phantom_widget_->GetNativeWindow()->layer(); | 220 ui::Layer* layer = phantom_widget_->GetNativeWindow()->layer(); |
| 152 layer->SetOpacity(0); | 221 layer->SetOpacity(0); |
| 153 ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator()); | 222 ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator()); |
| 154 layer->SetOpacity(1); | 223 layer->SetOpacity(1); |
| 155 } | 224 } |
| 156 | 225 |
| 226 void PhantomWindowController::SetBoundsInternal(const gfx::Rect& bounds) { |
| 227 aura::Window* window = phantom_widget_->GetNativeWindow(); |
| 228 aura::client::ScreenPositionClient* screen_position_client = |
| 229 aura::client::GetScreenPositionClient(window->GetRootWindow()); |
| 230 if (screen_position_client && dst_display_.id() != -1) |
| 231 screen_position_client->SetBounds(window, bounds, dst_display_); |
| 232 else |
| 233 phantom_widget_->SetBounds(bounds); |
| 234 } |
| 235 |
| 157 } // namespace internal | 236 } // namespace internal |
| 158 } // namespace ash | 237 } // namespace ash |
| OLD | NEW |