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/app_list/app_list.h" | 5 #include "ash/wm/app_list_controller.h" |
6 | 6 |
7 #include "ash/app_list/app_list_view.h" | |
8 #include "ash/app_list/icon_cache.h" | |
9 #include "ash/ash_switches.h" | 7 #include "ash/ash_switches.h" |
8 #include "ash/screen_ash.h" | |
10 #include "ash/shell.h" | 9 #include "ash/shell.h" |
11 #include "ash/shell_delegate.h" | 10 #include "ash/shell_delegate.h" |
12 #include "ash/shell_window_ids.h" | 11 #include "ash/shell_window_ids.h" |
13 #include "ash/wm/shelf_layout_manager.h" | 12 #include "ash/wm/shelf_layout_manager.h" |
14 #include "ash/wm/window_util.h" | 13 #include "ash/wm/window_util.h" |
15 #include "base/command_line.h" | 14 #include "base/command_line.h" |
15 #include "ui/app_list/app_list_view.h" | |
16 #include "ui/app_list/icon_cache.h" | |
16 #include "ui/aura/event.h" | 17 #include "ui/aura/event.h" |
17 #include "ui/aura/root_window.h" | 18 #include "ui/aura/root_window.h" |
18 #include "ui/aura/window.h" | 19 #include "ui/aura/window.h" |
19 #include "ui/compositor/layer.h" | 20 #include "ui/compositor/layer.h" |
20 #include "ui/compositor/scoped_layer_animation_settings.h" | 21 #include "ui/compositor/scoped_layer_animation_settings.h" |
22 #include "ui/gfx/screen.h" | |
21 #include "ui/gfx/transform_util.h" | 23 #include "ui/gfx/transform_util.h" |
22 | 24 |
23 namespace ash { | 25 namespace ash { |
24 namespace internal { | 26 namespace internal { |
25 | 27 |
26 namespace { | 28 namespace { |
27 | 29 |
28 const float kContainerAnimationScaleFactor = 1.05f; | 30 const float kContainerAnimationScaleFactor = 1.05f; |
29 | 31 |
30 // Duration for both default container and app list animation in milliseconds. | 32 // Duration for both default container and app list animation in milliseconds. |
31 const int kAnimationDurationMs = 130; | 33 const int kAnimationDurationMs = 130; |
32 | 34 |
33 // Delayed time of 2nd animation in milliseconds. | 35 // Delayed time of 2nd animation in milliseconds. |
34 const int kSecondAnimationStartDelay = kAnimationDurationMs - 20; | 36 const int kSecondAnimationStartDelay = kAnimationDurationMs - 20; |
35 | 37 |
36 ui::Layer* GetLayer(views::Widget* widget) { | 38 ui::Layer* GetLayer(views::Widget* widget) { |
37 return widget->GetNativeView()->layer(); | 39 return widget->GetNativeView()->layer(); |
38 } | 40 } |
39 | 41 |
42 // Bounds returned is used for full screen app list. Use full monitor rect | |
43 // so that the app list shade goes behind the launcher. | |
44 gfx::Rect GetFullScreenBoundsForWidget(views::Widget* widget) { | |
45 gfx::NativeView window = widget->GetNativeView(); | |
46 return gfx::Screen::GetMonitorNearestWindow(window).bounds(); | |
47 } | |
48 | |
49 // Return work area rect for full screen app list layout. This function is | |
50 // needed to get final work area in one shot instead of waiting for shelf | |
51 // animation to finish. | |
52 gfx::Rect GetWorkAreaBoundsForWidget(views::Widget* widget) { | |
53 gfx::NativeView window = widget->GetNativeView(); | |
54 return Shell::GetInstance()->shelf()->IsVisible() ? | |
55 ScreenAsh::GetUnmaximizedWorkAreaBounds(window) : | |
56 gfx::Screen::GetMonitorNearestWindow(window).work_area(); | |
57 } | |
58 | |
40 } // namespace | 59 } // namespace |
41 | 60 |
42 //////////////////////////////////////////////////////////////////////////////// | 61 //////////////////////////////////////////////////////////////////////////////// |
43 // AppList, public: | 62 // AppListController, public: |
44 | 63 |
45 AppList::AppList() : is_visible_(false), view_(NULL) { | 64 AppListController::AppListController() : is_visible_(false), view_(NULL) { |
46 IconCache::CreateInstance(); | 65 app_list::IconCache::CreateInstance(); |
47 } | 66 } |
48 | 67 |
49 AppList::~AppList() { | 68 AppListController::~AppListController() { |
50 ResetView(); | 69 ResetView(); |
51 IconCache::DeleteInstance(); | 70 app_list::IconCache::DeleteInstance(); |
52 } | 71 } |
53 | 72 |
54 // static | 73 // static |
55 bool AppList::UseAppListV2() { | 74 bool AppListController::UseAppListV2() { |
56 return CommandLine::ForCurrentProcess()->HasSwitch( | 75 return CommandLine::ForCurrentProcess()->HasSwitch( |
57 switches::kEnableAppListV2); | 76 switches::kEnableAppListV2); |
58 } | 77 } |
59 | 78 |
60 void AppList::SetVisible(bool visible) { | 79 void AppListController::SetVisible(bool visible) { |
61 if (visible == is_visible_) | 80 if (visible == is_visible_) |
62 return; | 81 return; |
63 | 82 |
64 is_visible_ = visible; | 83 is_visible_ = visible; |
65 | 84 |
66 // App list needs to know the new shelf layout in order to calculate its | 85 // App list needs to know the new shelf layout in order to calculate its |
67 // UI layout when AppListView visibility changes. | 86 // UI layout when AppListView visibility changes. |
68 Shell::GetInstance()->shelf()->UpdateAutoHideState(); | 87 Shell::GetInstance()->shelf()->UpdateAutoHideState(); |
69 | 88 |
70 if (view_) { | 89 if (view_) { |
71 ScheduleAnimation(); | 90 ScheduleAnimation(); |
72 } else if (is_visible_) { | 91 } else if (is_visible_) { |
73 // AppListModel and AppListViewDelegate are owned by AppListView. They | 92 // AppListModel and AppListViewDelegate are owned by AppListView. They |
74 // will be released with AppListView on close. | 93 // will be released with AppListView on close. |
75 SetView(new AppListView( | 94 app_list::AppListView* view = new app_list::AppListView( |
76 Shell::GetInstance()->delegate()->CreateAppListViewDelegate())); | 95 Shell::GetInstance()->delegate()->CreateAppListViewDelegate()); |
96 if (UseAppListV2()) { | |
97 view->InitAsBubble( | |
98 Shell::GetInstance()->GetContainer(kShellWindowId_AppListContainer), | |
99 Shell::GetInstance()->launcher()->GetAppListButtonView()); | |
100 } else { | |
101 views::Widget* launcher_widget = | |
102 Shell::GetInstance()->launcher()->widget(); | |
103 view->InitAsFullscreenWidget(Shell::GetInstance()->GetContainer( | |
104 kShellWindowId_AppListContainer), | |
105 GetFullScreenBoundsForWidget(launcher_widget), | |
106 GetWorkAreaBoundsForWidget(launcher_widget)); | |
107 } | |
108 SetView(view); | |
77 } | 109 } |
78 } | 110 } |
79 | 111 |
80 bool AppList::IsVisible() { | 112 bool AppListController::IsVisible() { |
81 return view_ && view_->GetWidget()->IsVisible(); | 113 return view_ && view_->GetWidget()->IsVisible(); |
82 } | 114 } |
83 | 115 |
84 aura::Window* AppList::GetWindow() { | 116 aura::Window* AppListController::GetWindow() { |
85 return is_visible_ && view_ ? view_->GetWidget()->GetNativeWindow() : NULL; | 117 return is_visible_ && view_ ? view_->GetWidget()->GetNativeWindow() : NULL; |
86 } | 118 } |
87 | 119 |
88 //////////////////////////////////////////////////////////////////////////////// | 120 //////////////////////////////////////////////////////////////////////////////// |
89 // AppList, private: | 121 // AppListController, private: |
90 | 122 |
91 void AppList::SetView(AppListView* view) { | 123 void AppListController::SetView(app_list::AppListView* view) { |
92 DCHECK(view_ == NULL); | 124 DCHECK(view_ == NULL); |
93 | 125 |
94 if (is_visible_) { | 126 if (is_visible_) { |
95 IconCache::GetInstance()->MarkAllEntryUnused(); | 127 app_list::IconCache::GetInstance()->MarkAllEntryUnused(); |
96 | 128 |
97 view_ = view; | 129 view_ = view; |
98 views::Widget* widget = view_->GetWidget(); | 130 views::Widget* widget = view_->GetWidget(); |
99 widget->AddObserver(this); | 131 widget->AddObserver(this); |
100 Shell::GetInstance()->AddRootWindowEventFilter(this); | 132 Shell::GetInstance()->AddRootWindowEventFilter(this); |
101 widget->GetNativeView()->GetRootWindow()->AddRootWindowObserver(this); | 133 widget->GetNativeView()->GetRootWindow()->AddRootWindowObserver(this); |
102 | 134 |
103 widget->SetOpacity(0); | 135 widget->SetOpacity(0); |
104 ScheduleAnimation(); | 136 ScheduleAnimation(); |
105 | 137 |
106 view_->GetWidget()->Show(); | 138 view_->GetWidget()->Show(); |
107 } else { | 139 } else { |
108 view->GetWidget()->Close(); | 140 view->GetWidget()->Close(); |
109 } | 141 } |
110 } | 142 } |
111 | 143 |
112 void AppList::ResetView() { | 144 void AppListController::ResetView() { |
113 if (!view_) | 145 if (!view_) |
114 return; | 146 return; |
115 | 147 |
116 views::Widget* widget = view_->GetWidget(); | 148 views::Widget* widget = view_->GetWidget(); |
117 widget->RemoveObserver(this); | 149 widget->RemoveObserver(this); |
118 GetLayer(widget)->GetAnimator()->RemoveObserver(this); | 150 GetLayer(widget)->GetAnimator()->RemoveObserver(this); |
119 Shell::GetInstance()->RemoveRootWindowEventFilter(this); | 151 Shell::GetInstance()->RemoveRootWindowEventFilter(this); |
120 widget->GetNativeView()->GetRootWindow()->RemoveRootWindowObserver(this); | 152 widget->GetNativeView()->GetRootWindow()->RemoveRootWindowObserver(this); |
121 view_ = NULL; | 153 view_ = NULL; |
122 | 154 |
123 IconCache::GetInstance()->PurgeAllUnused(); | 155 app_list::IconCache::GetInstance()->PurgeAllUnused(); |
124 } | 156 } |
125 | 157 |
126 void AppList::ScheduleAnimation() { | 158 void AppListController::ScheduleAnimation() { |
127 second_animation_timer_.Stop(); | 159 second_animation_timer_.Stop(); |
128 | 160 |
129 // Stop observing previous animation. | 161 // Stop observing previous animation. |
130 StopObservingImplicitAnimations(); | 162 StopObservingImplicitAnimations(); |
131 | 163 |
132 ScheduleDimmingAnimation(); | 164 ScheduleDimmingAnimation(); |
133 | 165 |
134 // No browser window fading and app list secondary animation for v2. | 166 // No browser window fading and app list secondary animation for v2. |
135 if (UseAppListV2()) | 167 if (UseAppListV2()) |
136 return; | 168 return; |
137 | 169 |
138 if (is_visible_) { | 170 if (is_visible_) { |
139 ScheduleBrowserWindowsAnimation(); | 171 ScheduleBrowserWindowsAnimation(); |
140 second_animation_timer_.Start( | 172 second_animation_timer_.Start( |
141 FROM_HERE, | 173 FROM_HERE, |
142 base::TimeDelta::FromMilliseconds(kSecondAnimationStartDelay), | 174 base::TimeDelta::FromMilliseconds(kSecondAnimationStartDelay), |
143 this, | 175 this, |
144 &AppList::ScheduleAppListAnimation); | 176 &AppListController::ScheduleAppListAnimation); |
145 } else { | 177 } else { |
146 ScheduleAppListAnimation(); | 178 ScheduleAppListAnimation(); |
147 second_animation_timer_.Start( | 179 second_animation_timer_.Start( |
148 FROM_HERE, | 180 FROM_HERE, |
149 base::TimeDelta::FromMilliseconds(kSecondAnimationStartDelay), | 181 base::TimeDelta::FromMilliseconds(kSecondAnimationStartDelay), |
150 this, | 182 this, |
151 &AppList::ScheduleBrowserWindowsAnimation); | 183 &AppListController::ScheduleBrowserWindowsAnimation); |
152 } | 184 } |
153 | |
154 } | 185 } |
155 | 186 |
156 void AppList::ScheduleBrowserWindowsAnimationForContainer( | 187 void AppListController::ScheduleBrowserWindowsAnimationForContainer( |
157 aura::Window* container) { | 188 aura::Window* container) { |
158 DCHECK(container); | 189 DCHECK(container); |
159 ui::Layer* layer = container->layer(); | 190 ui::Layer* layer = container->layer(); |
160 layer->GetAnimator()->StopAnimating(); | 191 layer->GetAnimator()->StopAnimating(); |
161 | 192 |
162 ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); | 193 ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); |
163 animation.SetTransitionDuration( | 194 animation.SetTransitionDuration( |
164 base::TimeDelta::FromMilliseconds(kAnimationDurationMs)); | 195 base::TimeDelta::FromMilliseconds(kAnimationDurationMs)); |
165 animation.SetTweenType( | 196 animation.SetTweenType( |
166 is_visible_ ? ui::Tween::EASE_IN : ui::Tween::EASE_OUT); | 197 is_visible_ ? ui::Tween::EASE_IN : ui::Tween::EASE_OUT); |
167 | 198 |
168 layer->SetOpacity(is_visible_ ? 0.0 : 1.0); | 199 layer->SetOpacity(is_visible_ ? 0.0 : 1.0); |
169 layer->SetTransform(is_visible_ ? | 200 layer->SetTransform(is_visible_ ? |
170 ui::GetScaleTransform( | 201 ui::GetScaleTransform( |
171 gfx::Point(layer->bounds().width() / 2, | 202 gfx::Point(layer->bounds().width() / 2, |
172 layer->bounds().height() / 2), | 203 layer->bounds().height() / 2), |
173 kContainerAnimationScaleFactor) : | 204 kContainerAnimationScaleFactor) : |
174 ui::Transform()); | 205 ui::Transform()); |
175 } | 206 } |
176 | 207 |
177 void AppList::ScheduleBrowserWindowsAnimation() { | 208 void AppListController::ScheduleBrowserWindowsAnimation() { |
178 // Note: containers could be NULL during Shell shutdown. | 209 // Note: containers could be NULL during Shell shutdown. |
179 aura::Window* default_container = Shell::GetInstance()->GetContainer( | 210 aura::Window* default_container = Shell::GetInstance()->GetContainer( |
180 internal::kShellWindowId_DefaultContainer); | 211 kShellWindowId_DefaultContainer); |
181 if (default_container) | 212 if (default_container) |
182 ScheduleBrowserWindowsAnimationForContainer(default_container); | 213 ScheduleBrowserWindowsAnimationForContainer(default_container); |
183 aura::Window* always_on_top_container = Shell::GetInstance()->GetContainer( | 214 aura::Window* always_on_top_container = Shell::GetInstance()-> |
184 internal::kShellWindowId_AlwaysOnTopContainer); | 215 GetContainer(kShellWindowId_AlwaysOnTopContainer); |
185 if (always_on_top_container) | 216 if (always_on_top_container) |
186 ScheduleBrowserWindowsAnimationForContainer(always_on_top_container); | 217 ScheduleBrowserWindowsAnimationForContainer(always_on_top_container); |
187 } | 218 } |
188 | 219 |
189 void AppList::ScheduleDimmingAnimation() { | 220 void AppListController::ScheduleDimmingAnimation() { |
190 ui::Layer* layer = GetLayer(view_->GetWidget()); | 221 ui::Layer* layer = GetLayer(view_->GetWidget()); |
191 layer->GetAnimator()->StopAnimating(); | 222 layer->GetAnimator()->StopAnimating(); |
192 | 223 |
193 int duration = UseAppListV2() ? | 224 int duration = UseAppListV2() ? |
194 kAnimationDurationMs : 2 * kAnimationDurationMs; | 225 kAnimationDurationMs : 2 * kAnimationDurationMs; |
195 | 226 |
196 ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); | 227 ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); |
197 animation.SetTransitionDuration( | 228 animation.SetTransitionDuration( |
198 base::TimeDelta::FromMilliseconds(duration)); | 229 base::TimeDelta::FromMilliseconds(duration)); |
199 animation.AddObserver(this); | 230 animation.AddObserver(this); |
200 | 231 |
201 layer->SetOpacity(is_visible_ ? 1.0 : 0.0); | 232 layer->SetOpacity(is_visible_ ? 1.0 : 0.0); |
202 } | 233 } |
203 | 234 |
204 void AppList::ScheduleAppListAnimation() { | 235 void AppListController::ScheduleAppListAnimation() { |
205 if (is_visible_) | 236 if (is_visible_) |
206 view_->AnimateShow(kAnimationDurationMs); | 237 view_->AnimateShow(kAnimationDurationMs); |
207 else | 238 else |
208 view_->AnimateHide(kAnimationDurationMs); | 239 view_->AnimateHide(kAnimationDurationMs); |
209 } | 240 } |
210 | 241 |
211 //////////////////////////////////////////////////////////////////////////////// | 242 //////////////////////////////////////////////////////////////////////////////// |
212 // AppList, aura::EventFilter implementation: | 243 // AppListController, aura::EventFilter implementation: |
213 | 244 |
214 bool AppList::PreHandleKeyEvent(aura::Window* target, | 245 bool AppListController::PreHandleKeyEvent(aura::Window* target, |
215 aura::KeyEvent* event) { | 246 aura::KeyEvent* event) { |
tfarina
2012/05/09 00:35:18
nit: fix indentation here and below.
xiyuan
2012/05/09 01:28:46
Done.
| |
216 return false; | 247 return false; |
217 } | 248 } |
218 | 249 |
219 bool AppList::PreHandleMouseEvent(aura::Window* target, | 250 bool AppListController::PreHandleMouseEvent(aura::Window* target, |
220 aura::MouseEvent* event) { | 251 aura::MouseEvent* event) { |
221 if (view_ && is_visible_ && event->type() == ui::ET_MOUSE_PRESSED) { | 252 if (view_ && is_visible_ && event->type() == ui::ET_MOUSE_PRESSED) { |
222 views::Widget* widget = view_->GetWidget(); | 253 views::Widget* widget = view_->GetWidget(); |
223 aura::MouseEvent translated(*event, target, widget->GetNativeView()); | 254 aura::MouseEvent translated(*event, target, widget->GetNativeView()); |
224 if (!widget->GetNativeView()->ContainsPoint(translated.location())) | 255 if (!widget->GetNativeView()->ContainsPoint(translated.location())) |
225 SetVisible(false); | 256 SetVisible(false); |
226 } | 257 } |
227 return false; | 258 return false; |
228 } | 259 } |
229 | 260 |
230 ui::TouchStatus AppList::PreHandleTouchEvent(aura::Window* target, | 261 ui::TouchStatus AppListController::PreHandleTouchEvent(aura::Window* target, |
231 aura::TouchEvent* event) { | 262 aura::TouchEvent* event) { |
232 return ui::TOUCH_STATUS_UNKNOWN; | 263 return ui::TOUCH_STATUS_UNKNOWN; |
233 } | 264 } |
234 | 265 |
235 ui::GestureStatus AppList::PreHandleGestureEvent( | 266 ui::GestureStatus AppListController::PreHandleGestureEvent( |
236 aura::Window* target, | 267 aura::Window* target, |
237 aura::GestureEvent* event) { | 268 aura::GestureEvent* event) { |
238 return ui::GESTURE_STATUS_UNKNOWN; | 269 return ui::GESTURE_STATUS_UNKNOWN; |
239 } | 270 } |
240 | 271 |
241 //////////////////////////////////////////////////////////////////////////////// | 272 //////////////////////////////////////////////////////////////////////////////// |
242 // AppList, ura::RootWindowObserver implementation: | 273 // AppListController, aura::RootWindowObserver implementation: |
243 void AppList::OnRootWindowResized(const aura::RootWindow* root, | 274 void AppListController::OnRootWindowResized(const aura::RootWindow* root, |
244 const gfx::Size& old_size) { | 275 const gfx::Size& old_size) { |
245 if (view_ && is_visible_) | 276 if (view_ && is_visible_) { |
246 view_->UpdateBounds(); | 277 views::Widget* launcher_widget = |
278 Shell::GetInstance()->launcher()->widget(); | |
279 view_->UpdateBounds(GetFullScreenBoundsForWidget(launcher_widget), | |
280 GetWorkAreaBoundsForWidget(launcher_widget)); | |
281 } | |
247 } | 282 } |
248 | 283 |
249 void AppList::OnWindowFocused(aura::Window* window) { | 284 void AppListController::OnWindowFocused(aura::Window* window) { |
250 if (view_ && is_visible_) { | 285 if (view_ && is_visible_) { |
251 aura::Window* applist_container = Shell::GetInstance()->GetContainer( | 286 aura::Window* applist_container = Shell::GetInstance()->GetContainer( |
252 internal::kShellWindowId_AppListContainer); | 287 kShellWindowId_AppListContainer); |
253 aura::Window* bubble_container = Shell::GetInstance()->GetContainer( | 288 aura::Window* bubble_container = Shell::GetInstance()->GetContainer( |
254 internal::kShellWindowId_SettingBubbleContainer); | 289 kShellWindowId_SettingBubbleContainer); |
255 if (window->parent() != applist_container && | 290 if (window->parent() != applist_container && |
256 window->parent() != bubble_container) { | 291 window->parent() != bubble_container) { |
257 SetVisible(false); | 292 SetVisible(false); |
258 } | 293 } |
259 } | 294 } |
260 } | 295 } |
261 | 296 |
262 //////////////////////////////////////////////////////////////////////////////// | 297 //////////////////////////////////////////////////////////////////////////////// |
263 // AppList, ui::ImplicitAnimationObserver implementation: | 298 // AppListController, ui::ImplicitAnimationObserver implementation: |
264 | 299 |
265 void AppList::OnImplicitAnimationsCompleted() { | 300 void AppListController::OnImplicitAnimationsCompleted() { |
266 if (is_visible_ ) | 301 if (is_visible_ ) |
267 view_->GetWidget()->Activate(); | 302 view_->GetWidget()->Activate(); |
268 else | 303 else |
269 view_->GetWidget()->Close(); | 304 view_->GetWidget()->Close(); |
270 } | 305 } |
271 | 306 |
272 //////////////////////////////////////////////////////////////////////////////// | 307 //////////////////////////////////////////////////////////////////////////////// |
273 // AppList, views::Widget::Observer implementation: | 308 // AppListController, views::Widget::Observer implementation: |
274 | 309 |
275 void AppList::OnWidgetClosing(views::Widget* widget) { | 310 void AppListController::OnWidgetClosing(views::Widget* widget) { |
276 DCHECK(view_->GetWidget() == widget); | 311 DCHECK(view_->GetWidget() == widget); |
277 if (is_visible_) | 312 if (is_visible_) |
278 SetVisible(false); | 313 SetVisible(false); |
279 ResetView(); | 314 ResetView(); |
280 } | 315 } |
281 | 316 |
282 } // namespace internal | 317 } // namespace internal |
283 } // namespace ash | 318 } // namespace ash |
OLD | NEW |