Chromium Code Reviews| 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 { | |
|
sky
2012/08/09 21:57:27
This won't include any child windows the window ma
Yusuke Sato
2012/08/10 00:30:49
Would you mind if I implement this in another CL?
sky
2012/08/10 16:06:36
If you make this paint an empty square, I'm ok wit
| |
| 93 if (window_ && window_->delegate()) | |
| 94 window_->delegate()->OnPaint(canvas); | |
| 95 } | |
| 96 | |
| 97 private: | |
| 98 // aura::WindowObserver overrides: | |
| 99 virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE { | |
| 100 DCHECK_EQ(window_, window); | |
| 101 window_ = NULL; | |
| 102 } | |
| 103 | |
| 104 aura::Window* window_; | |
| 105 | |
| 106 DISALLOW_COPY_AND_ASSIGN(WindowPainter); | |
| 107 }; | |
| 108 | |
| 73 } // namespace | 109 } // namespace |
| 74 | 110 |
| 75 PhantomWindowController::PhantomWindowController(aura::Window* window) | 111 PhantomWindowController::PhantomWindowController(aura::Window* window) |
| 76 : window_(window), | 112 : window_(window), |
| 77 phantom_below_window_(NULL), | 113 phantom_below_window_(NULL), |
| 78 phantom_widget_(NULL) { | 114 phantom_widget_(NULL), |
| 115 style_(STYLE_SHADOW) { | |
| 79 } | 116 } |
| 80 | 117 |
| 81 PhantomWindowController::~PhantomWindowController() { | 118 PhantomWindowController::~PhantomWindowController() { |
| 82 Hide(); | 119 Hide(); |
| 83 } | 120 } |
| 84 | 121 |
| 122 void PhantomWindowController::SetDestinationDisplay( | |
| 123 const gfx::Display& dst_display) { | |
| 124 dst_display_ = dst_display; | |
| 125 } | |
| 126 | |
| 85 void PhantomWindowController::Show(const gfx::Rect& bounds) { | 127 void PhantomWindowController::Show(const gfx::Rect& bounds) { |
| 86 if (bounds == bounds_) | 128 if (bounds == bounds_) |
| 87 return; | 129 return; |
| 88 bounds_ = bounds; | 130 bounds_ = bounds; |
| 89 if (!phantom_widget_) { | 131 if (!phantom_widget_) { |
| 90 // Show the phantom at the bounds of the window. We'll animate to the target | 132 // Show the phantom at the bounds of the window. We'll animate to the target |
| 91 // bounds. | 133 // bounds. |
| 92 start_bounds_ = window_->GetBoundsInScreen(); | 134 start_bounds_ = window_->GetBoundsInScreen(); |
| 93 CreatePhantomWidget(start_bounds_); | 135 CreatePhantomWidget(start_bounds_); |
| 94 } else { | 136 } else { |
| 95 start_bounds_ = phantom_widget_->GetWindowBoundsInScreen(); | 137 start_bounds_ = phantom_widget_->GetWindowBoundsInScreen(); |
| 96 } | 138 } |
| 97 animation_.reset(new ui::SlideAnimation(this)); | 139 animation_.reset(new ui::SlideAnimation(this)); |
| 98 animation_->Show(); | 140 animation_->Show(); |
| 99 } | 141 } |
| 100 | 142 |
| 101 void PhantomWindowController::SetBounds(const gfx::Rect& bounds) { | 143 void PhantomWindowController::SetBounds(const gfx::Rect& bounds) { |
| 102 DCHECK(IsShowing()); | 144 DCHECK(IsShowing()); |
| 103 animation_.reset(); | 145 animation_.reset(); |
| 104 bounds_ = bounds; | 146 bounds_ = bounds; |
| 105 phantom_widget_->SetBounds(bounds_); | 147 SetBoundsInternal(bounds); |
| 106 } | 148 } |
| 107 | 149 |
| 108 void PhantomWindowController::Hide() { | 150 void PhantomWindowController::Hide() { |
| 109 if (phantom_widget_) | 151 if (phantom_widget_) |
| 110 phantom_widget_->Close(); | 152 phantom_widget_->Close(); |
| 111 phantom_widget_ = NULL; | 153 phantom_widget_ = NULL; |
| 112 } | 154 } |
| 113 | 155 |
| 114 bool PhantomWindowController::IsShowing() const { | 156 bool PhantomWindowController::IsShowing() const { |
| 115 return phantom_widget_ != NULL; | 157 return phantom_widget_ != NULL; |
| 116 } | 158 } |
| 117 | 159 |
| 160 void PhantomWindowController::set_style(Style style) { | |
| 161 DCHECK(!phantom_widget_); | |
| 162 style_ = style; | |
| 163 } | |
| 164 | |
| 165 void PhantomWindowController::SetOpacity(float opacity) { | |
| 166 if (!phantom_widget_) | |
|
sky
2012/08/09 21:57:27
I don't like that set_style and SetOpacity have di
Yusuke Sato
2012/08/10 00:30:49
Done.
| |
| 167 return; | |
| 168 ui::Layer* layer = phantom_widget_->GetNativeWindow()->layer(); | |
| 169 ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator()); | |
| 170 layer->SetOpacity(opacity); | |
| 171 } | |
| 172 | |
| 173 float PhantomWindowController::GetOpacity() const { | |
| 174 if (!phantom_widget_) | |
| 175 return 0; | |
| 176 return phantom_widget_->GetNativeWindow()->layer()->opacity(); | |
| 177 } | |
| 178 | |
| 118 void PhantomWindowController::AnimationProgressed( | 179 void PhantomWindowController::AnimationProgressed( |
| 119 const ui::Animation* animation) { | 180 const ui::Animation* animation) { |
| 120 phantom_widget_->SetBounds( | 181 SetBoundsInternal(animation->CurrentValueBetween(start_bounds_, bounds_)); |
| 121 animation->CurrentValueBetween(start_bounds_, bounds_)); | |
| 122 } | 182 } |
| 123 | 183 |
| 124 void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) { | 184 void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) { |
| 125 DCHECK(!phantom_widget_); | 185 DCHECK(!phantom_widget_); |
| 126 phantom_widget_ = new views::Widget; | 186 phantom_widget_ = new views::Widget; |
| 127 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); | 187 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); |
| 128 params.transparent = true; | 188 params.transparent = true; |
| 129 // PhantomWindowController is used by FrameMaximizeButton to highlight the | 189 // PhantomWindowController is used by FrameMaximizeButton to highlight the |
| 130 // launcher button. Put the phantom in the same window as the launcher so that | 190 // launcher button. Put the phantom in the same window as the launcher so that |
| 131 // the phantom is visible. | 191 // the phantom is visible. |
| 132 params.parent = Shell::GetContainer(wm::GetRootWindowMatching(bounds), | 192 params.parent = Shell::GetContainer(wm::GetRootWindowMatching(bounds), |
| 133 kShellWindowId_LauncherContainer); | 193 kShellWindowId_LauncherContainer); |
| 134 params.can_activate = false; | 194 params.can_activate = false; |
| 135 params.keep_on_top = true; | 195 params.keep_on_top = true; |
| 136 phantom_widget_->set_focus_on_creation(false); | 196 phantom_widget_->set_focus_on_creation(false); |
| 137 phantom_widget_->Init(params); | 197 phantom_widget_->Init(params); |
| 138 phantom_widget_->SetVisibilityChangedAnimationsEnabled(false); | 198 phantom_widget_->SetVisibilityChangedAnimationsEnabled(false); |
| 139 phantom_widget_->GetNativeWindow()->SetName("PhantomWindow"); | 199 phantom_widget_->GetNativeWindow()->SetName("PhantomWindow"); |
| 140 views::View* content_view = new views::View; | 200 views::View* content_view = new views::View; |
| 141 content_view->set_background( | 201 switch (style_) { |
| 142 views::Background::CreateBackgroundPainter(true, new EdgePainter)); | 202 case STYLE_SHADOW: |
| 203 content_view->set_background( | |
| 204 views::Background::CreateBackgroundPainter(true, new EdgePainter)); | |
| 205 break; | |
| 206 case STYLE_WINDOW: | |
| 207 content_view->set_background(views::Background::CreateBackgroundPainter( | |
| 208 true, new WindowPainter(window_))); | |
| 209 break; | |
| 210 } | |
| 143 phantom_widget_->SetContentsView(content_view); | 211 phantom_widget_->SetContentsView(content_view); |
| 144 phantom_widget_->SetBounds(bounds); | 212 SetBoundsInternal(bounds); |
| 145 if (phantom_below_window_) | 213 if (phantom_below_window_) |
| 146 phantom_widget_->StackBelow(phantom_below_window_); | 214 phantom_widget_->StackBelow(phantom_below_window_); |
| 147 else | 215 else |
| 148 phantom_widget_->StackAbove(window_); | 216 phantom_widget_->StackAbove(window_); |
| 149 phantom_widget_->Show(); | 217 phantom_widget_->Show(); |
| 150 // Fade the window in. | 218 // Fade the window in. |
| 151 ui::Layer* layer = phantom_widget_->GetNativeWindow()->layer(); | 219 ui::Layer* layer = phantom_widget_->GetNativeWindow()->layer(); |
| 152 layer->SetOpacity(0); | 220 layer->SetOpacity(0); |
| 153 ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator()); | 221 ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator()); |
| 154 layer->SetOpacity(1); | 222 layer->SetOpacity(1); |
| 155 } | 223 } |
| 156 | 224 |
| 225 void PhantomWindowController::SetBoundsInternal(const gfx::Rect& bounds) { | |
| 226 aura::Window* window = phantom_widget_->GetNativeWindow(); | |
| 227 aura::client::ScreenPositionClient* screen_position_client = | |
| 228 aura::client::GetScreenPositionClient(window->GetRootWindow()); | |
| 229 if (screen_position_client && dst_display_.id() != -1) | |
| 230 screen_position_client->SetBounds(window, bounds, dst_display_); | |
| 231 else | |
| 232 phantom_widget_->SetBounds(bounds); | |
| 233 } | |
| 234 | |
| 157 } // namespace internal | 235 } // namespace internal |
| 158 } // namespace ash | 236 } // namespace ash |
| OLD | NEW |