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 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, |
112 aura::RootWindow* root_window, | |
sky
2012/08/09 16:23:16
I would rather see a set_style and SetDestinationD
Yusuke Sato
2012/08/09 20:00:17
Done.
| |
113 Style style) | |
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) { | |
118 if (root_window) { | |
119 dst_display_ = | |
120 gfx::Screen::GetDisplayMatching(root_window->GetBoundsInScreen()); | |
121 } | |
79 } | 122 } |
80 | 123 |
81 PhantomWindowController::~PhantomWindowController() { | 124 PhantomWindowController::~PhantomWindowController() { |
82 Hide(); | 125 Hide(); |
83 } | 126 } |
84 | 127 |
85 void PhantomWindowController::Show(const gfx::Rect& bounds) { | 128 void PhantomWindowController::Show(const gfx::Rect& bounds) { |
86 if (bounds == bounds_) | 129 if (bounds == bounds_) |
87 return; | 130 return; |
88 bounds_ = bounds; | 131 bounds_ = bounds; |
89 if (!phantom_widget_) { | 132 if (!phantom_widget_) { |
90 // Show the phantom at the bounds of the window. We'll animate to the target | 133 // Show the phantom at the bounds of the window. We'll animate to the target |
91 // bounds. | 134 // bounds. |
92 start_bounds_ = window_->GetBoundsInScreen(); | 135 start_bounds_ = window_->GetBoundsInScreen(); |
93 CreatePhantomWidget(start_bounds_); | 136 CreatePhantomWidget(start_bounds_); |
94 } else { | 137 } else { |
95 start_bounds_ = phantom_widget_->GetWindowBoundsInScreen(); | 138 start_bounds_ = phantom_widget_->GetWindowBoundsInScreen(); |
96 } | 139 } |
97 animation_.reset(new ui::SlideAnimation(this)); | 140 animation_.reset(new ui::SlideAnimation(this)); |
98 animation_->Show(); | 141 animation_->Show(); |
99 } | 142 } |
100 | 143 |
101 void PhantomWindowController::SetBounds(const gfx::Rect& bounds) { | 144 void PhantomWindowController::SetBounds(const gfx::Rect& bounds) { |
102 DCHECK(IsShowing()); | 145 DCHECK(IsShowing()); |
103 animation_.reset(); | 146 animation_.reset(); |
104 bounds_ = bounds; | 147 bounds_ = bounds; |
105 phantom_widget_->SetBounds(bounds_); | 148 SetBoundsInternal(bounds); |
106 } | 149 } |
107 | 150 |
108 void PhantomWindowController::Hide() { | 151 void PhantomWindowController::Hide() { |
109 if (phantom_widget_) | 152 if (phantom_widget_) |
110 phantom_widget_->Close(); | 153 phantom_widget_->Close(); |
111 phantom_widget_ = NULL; | 154 phantom_widget_ = NULL; |
112 } | 155 } |
113 | 156 |
114 bool PhantomWindowController::IsShowing() const { | 157 bool PhantomWindowController::IsShowing() const { |
115 return phantom_widget_ != NULL; | 158 return phantom_widget_ != NULL; |
116 } | 159 } |
117 | 160 |
161 void PhantomWindowController::SetOpacity(float opacity) { | |
162 ui::Layer* layer = phantom_widget_->GetNativeWindow()->layer(); | |
sky
2012/08/09 16:23:16
phantom_widget_ may be NULL.
Yusuke Sato
2012/08/09 20:00:17
Thanks. Done.
| |
163 ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator()); | |
164 layer->SetOpacity(opacity); | |
165 } | |
166 | |
167 float PhantomWindowController::GetOpacity() const { | |
168 return phantom_widget_->GetNativeWindow()->layer()->opacity(); | |
sky
2012/08/09 16:23:16
phanton_widget_ may be NULL.
Yusuke Sato
2012/08/09 20:00:17
Done.
| |
169 } | |
170 | |
118 void PhantomWindowController::AnimationProgressed( | 171 void PhantomWindowController::AnimationProgressed( |
119 const ui::Animation* animation) { | 172 const ui::Animation* animation) { |
120 phantom_widget_->SetBounds( | 173 SetBoundsInternal(animation->CurrentValueBetween(start_bounds_, bounds_)); |
121 animation->CurrentValueBetween(start_bounds_, bounds_)); | |
122 } | 174 } |
123 | 175 |
124 void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) { | 176 void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) { |
125 DCHECK(!phantom_widget_); | 177 DCHECK(!phantom_widget_); |
126 phantom_widget_ = new views::Widget; | 178 phantom_widget_ = new views::Widget; |
127 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); | 179 views::Widget::InitParams params; |
180 switch (style_) { | |
181 case STYLE_SHADOW: | |
182 params.type = views::Widget::InitParams::TYPE_POPUP; | |
183 break; | |
184 case STYLE_WINDOW: | |
185 params.type = views::Widget::InitParams::TYPE_WINDOW; | |
sky
2012/08/09 16:23:16
Why does this need to be a WINDOW?
Yusuke Sato
2012/08/09 20:00:17
POPUP is fine. Reverted this part. Thanks.
| |
186 break; | |
187 } | |
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 |