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 "ui/app_list/views/app_list_view.h" | 5 #include "ui/app_list/views/app_list_view.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
9 #include "ui/app_list/app_list_constants.h" | 9 #include "ui/app_list/app_list_constants.h" |
10 #include "ui/app_list/app_list_model.h" | 10 #include "ui/app_list/app_list_model.h" |
11 #include "ui/app_list/app_list_view_delegate.h" | 11 #include "ui/app_list/app_list_view_delegate.h" |
12 #include "ui/app_list/pagination_model.h" | 12 #include "ui/app_list/pagination_model.h" |
13 #include "ui/app_list/signin_delegate.h" | 13 #include "ui/app_list/signin_delegate.h" |
| 14 #include "ui/app_list/speech_ui_model.h" |
14 #include "ui/app_list/views/app_list_background.h" | 15 #include "ui/app_list/views/app_list_background.h" |
15 #include "ui/app_list/views/app_list_main_view.h" | 16 #include "ui/app_list/views/app_list_main_view.h" |
16 #include "ui/app_list/views/app_list_view_observer.h" | 17 #include "ui/app_list/views/app_list_view_observer.h" |
17 #include "ui/app_list/views/search_box_view.h" | 18 #include "ui/app_list/views/search_box_view.h" |
18 #include "ui/app_list/views/signin_view.h" | 19 #include "ui/app_list/views/signin_view.h" |
| 20 #include "ui/app_list/views/speech_view.h" |
19 #include "ui/base/ui_base_switches.h" | 21 #include "ui/base/ui_base_switches.h" |
| 22 #include "ui/compositor/layer.h" |
| 23 #include "ui/compositor/scoped_layer_animation_settings.h" |
20 #include "ui/gfx/image/image_skia.h" | 24 #include "ui/gfx/image/image_skia.h" |
21 #include "ui/gfx/insets.h" | 25 #include "ui/gfx/insets.h" |
22 #include "ui/gfx/path.h" | 26 #include "ui/gfx/path.h" |
23 #include "ui/gfx/skia_util.h" | 27 #include "ui/gfx/skia_util.h" |
24 #include "ui/views/bubble/bubble_frame_view.h" | 28 #include "ui/views/bubble/bubble_frame_view.h" |
25 #include "ui/views/controls/textfield/textfield.h" | 29 #include "ui/views/controls/textfield/textfield.h" |
26 #include "ui/views/layout/fill_layout.h" | 30 #include "ui/views/layout/fill_layout.h" |
27 #include "ui/views/widget/widget.h" | 31 #include "ui/views/widget/widget.h" |
28 | 32 |
29 #if defined(USE_AURA) | 33 #if defined(USE_AURA) |
30 #include "ui/aura/window.h" | 34 #include "ui/aura/window.h" |
31 #include "ui/aura/root_window.h" | 35 #include "ui/aura/root_window.h" |
32 #if defined(OS_WIN) | 36 #if defined(OS_WIN) |
33 #include "ui/base/win/shell.h" | 37 #include "ui/base/win/shell.h" |
34 #endif | 38 #endif |
35 #if !defined(OS_CHROMEOS) | 39 #if !defined(OS_CHROMEOS) |
36 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" | 40 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" |
37 #endif | 41 #endif |
38 #endif // defined(USE_AURA) | 42 #endif // defined(USE_AURA) |
39 | 43 |
40 namespace app_list { | 44 namespace app_list { |
41 | 45 |
42 namespace { | 46 namespace { |
43 | 47 |
44 void (*g_next_paint_callback)(); | 48 void (*g_next_paint_callback)(); |
45 | 49 |
| 50 // The margin from the edge to the speech UI. |
| 51 const int kSpeechUIMargin = 12; |
| 52 |
| 53 // The vertical position for the appearing animation of the speech UI. |
| 54 const float kSpeechUIApearingPosition =12; |
| 55 |
46 // The distance between the arrow tip and edge of the anchor view. | 56 // The distance between the arrow tip and edge of the anchor view. |
47 const int kArrowOffset = 10; | 57 const int kArrowOffset = 10; |
48 | 58 |
49 #if defined(OS_LINUX) | 59 #if defined(OS_LINUX) |
50 // The WM_CLASS name for the app launcher window on Linux. | 60 // The WM_CLASS name for the app launcher window on Linux. |
51 const char* kAppListWMClass = "chrome_app_list"; | 61 const char* kAppListWMClass = "chrome_app_list"; |
52 #endif | 62 #endif |
53 | 63 |
54 // Determines whether the current environment supports shadows bubble borders. | 64 // Determines whether the current environment supports shadows bubble borders. |
55 bool SupportsShadow() { | 65 bool SupportsShadow() { |
56 #if defined(USE_AURA) && defined(OS_WIN) | 66 #if defined(USE_AURA) && defined(OS_WIN) |
57 // Shadows are not supported on Windows Aura without Aero Glass. | 67 // Shadows are not supported on Windows Aura without Aero Glass. |
58 if (!ui::win::IsAeroGlassEnabled() || | 68 if (!ui::win::IsAeroGlassEnabled() || |
59 CommandLine::ForCurrentProcess()->HasSwitch( | 69 CommandLine::ForCurrentProcess()->HasSwitch( |
60 switches::kDisableDwmComposition)) { | 70 switches::kDisableDwmComposition)) { |
61 return false; | 71 return false; |
62 } | 72 } |
63 #elif defined(OS_LINUX) && !defined(USE_ASH) | 73 #elif defined(OS_LINUX) && !defined(USE_ASH) |
64 // Shadows are not supported on (non-ChromeOS) Linux. | 74 // Shadows are not supported on (non-ChromeOS) Linux. |
65 return false; | 75 return false; |
66 #endif | 76 #endif |
67 return true; | 77 return true; |
68 } | 78 } |
69 | 79 |
70 } // namespace | 80 } // namespace |
71 | 81 |
| 82 // An animation observer to hide the view at the end of the animation. |
| 83 class HideViewAnimationObserver : public ui::ImplicitAnimationObserver { |
| 84 public: |
| 85 HideViewAnimationObserver() : target_(NULL) { |
| 86 } |
| 87 |
| 88 virtual ~HideViewAnimationObserver() { |
| 89 if (target_) |
| 90 StopObservingImplicitAnimations(); |
| 91 } |
| 92 |
| 93 void SetTarget(views::View* target) { |
| 94 if (!target_) |
| 95 StopObservingImplicitAnimations(); |
| 96 target_ = target; |
| 97 } |
| 98 |
| 99 private: |
| 100 // Overridden from ui::ImplicitAnimationObserver: |
| 101 virtual void OnImplicitAnimationsCompleted() OVERRIDE { |
| 102 if (target_) { |
| 103 target_->SetVisible(false); |
| 104 target_ = NULL; |
| 105 } |
| 106 } |
| 107 |
| 108 views::View* target_; |
| 109 |
| 110 DISALLOW_COPY_AND_ASSIGN(HideViewAnimationObserver); |
| 111 }; |
| 112 |
72 //////////////////////////////////////////////////////////////////////////////// | 113 //////////////////////////////////////////////////////////////////////////////// |
73 // AppListView: | 114 // AppListView: |
74 | 115 |
75 AppListView::AppListView(AppListViewDelegate* delegate) | 116 AppListView::AppListView(AppListViewDelegate* delegate) |
76 : delegate_(delegate), | 117 : delegate_(delegate), |
77 app_list_main_view_(NULL), | 118 app_list_main_view_(NULL), |
78 signin_view_(NULL) { | 119 signin_view_(NULL), |
| 120 speech_view_(NULL), |
| 121 animation_observer_(new HideViewAnimationObserver()) { |
79 CHECK(delegate); | 122 CHECK(delegate); |
| 123 |
80 delegate_->AddObserver(this); | 124 delegate_->AddObserver(this); |
| 125 delegate_->GetSpeechUI()->AddObserver(this); |
81 } | 126 } |
82 | 127 |
83 AppListView::~AppListView() { | 128 AppListView::~AppListView() { |
| 129 delegate_->GetSpeechUI()->RemoveObserver(this); |
84 delegate_->RemoveObserver(this); | 130 delegate_->RemoveObserver(this); |
| 131 animation_observer_.reset(); |
85 // Remove child views first to ensure no remaining dependencies on delegate_. | 132 // Remove child views first to ensure no remaining dependencies on delegate_. |
86 RemoveAllChildViews(true); | 133 RemoveAllChildViews(true); |
87 } | 134 } |
88 | 135 |
89 void AppListView::InitAsBubbleAttachedToAnchor( | 136 void AppListView::InitAsBubbleAttachedToAnchor( |
90 gfx::NativeView parent, | 137 gfx::NativeView parent, |
91 PaginationModel* pagination_model, | 138 PaginationModel* pagination_model, |
92 views::View* anchor, | 139 views::View* anchor, |
93 const gfx::Vector2d& anchor_offset, | 140 const gfx::Vector2d& anchor_offset, |
94 views::BubbleBorder::Arrow arrow, | 141 views::BubbleBorder::Arrow arrow, |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 app_list_main_view_->SetPaintToLayer(true); | 257 app_list_main_view_->SetPaintToLayer(true); |
211 app_list_main_view_->SetFillsBoundsOpaquely(false); | 258 app_list_main_view_->SetFillsBoundsOpaquely(false); |
212 app_list_main_view_->layer()->SetMasksToBounds(true); | 259 app_list_main_view_->layer()->SetMasksToBounds(true); |
213 #endif | 260 #endif |
214 | 261 |
215 signin_view_ = | 262 signin_view_ = |
216 new SigninView(delegate_->GetSigninDelegate(), | 263 new SigninView(delegate_->GetSigninDelegate(), |
217 app_list_main_view_->GetPreferredSize().width()); | 264 app_list_main_view_->GetPreferredSize().width()); |
218 AddChildView(signin_view_); | 265 AddChildView(signin_view_); |
219 | 266 |
| 267 // Speech recognition is available only when the start page exists. |
| 268 if (delegate_ && delegate_->GetStartPageContents()) { |
| 269 speech_view_ = new SpeechView(delegate_.get()); |
| 270 speech_view_->SetVisible(false); |
| 271 #if defined(USE_AURA) |
| 272 speech_view_->SetPaintToLayer(true); |
| 273 speech_view_->SetFillsBoundsOpaquely(false); |
| 274 speech_view_->layer()->SetOpacity(0.0f); |
| 275 #endif |
| 276 AddChildView(speech_view_); |
| 277 } |
| 278 |
220 OnProfilesChanged(); | 279 OnProfilesChanged(); |
221 set_color(kContentsBackgroundColor); | 280 set_color(kContentsBackgroundColor); |
222 set_margins(gfx::Insets()); | 281 set_margins(gfx::Insets()); |
223 set_move_with_anchor(true); | 282 set_move_with_anchor(true); |
224 set_parent_window(parent); | 283 set_parent_window(parent); |
225 set_close_on_deactivate(false); | 284 set_close_on_deactivate(false); |
226 set_close_on_esc(false); | 285 set_close_on_esc(false); |
227 set_anchor_view_insets(gfx::Insets(kArrowOffset + anchor_offset.y(), | 286 set_anchor_view_insets(gfx::Insets(kArrowOffset + anchor_offset.y(), |
228 kArrowOffset + anchor_offset.x(), | 287 kArrowOffset + anchor_offset.x(), |
229 kArrowOffset - anchor_offset.y(), | 288 kArrowOffset - anchor_offset.y(), |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 return true; | 360 return true; |
302 } | 361 } |
303 | 362 |
304 return false; | 363 return false; |
305 } | 364 } |
306 | 365 |
307 void AppListView::Layout() { | 366 void AppListView::Layout() { |
308 const gfx::Rect contents_bounds = GetContentsBounds(); | 367 const gfx::Rect contents_bounds = GetContentsBounds(); |
309 app_list_main_view_->SetBoundsRect(contents_bounds); | 368 app_list_main_view_->SetBoundsRect(contents_bounds); |
310 signin_view_->SetBoundsRect(contents_bounds); | 369 signin_view_->SetBoundsRect(contents_bounds); |
| 370 |
| 371 if (speech_view_) { |
| 372 gfx::Rect speech_bounds = contents_bounds; |
| 373 int preferred_height = speech_view_->GetPreferredSize().height(); |
| 374 speech_bounds.Inset(kSpeechUIMargin, kSpeechUIMargin); |
| 375 speech_bounds.set_height(std::min(speech_bounds.height(), |
| 376 preferred_height)); |
| 377 speech_bounds.Inset(-speech_view_->GetInsets()); |
| 378 speech_view_->SetBoundsRect(speech_bounds); |
| 379 } |
311 } | 380 } |
312 | 381 |
313 void AppListView::OnWidgetDestroying(views::Widget* widget) { | 382 void AppListView::OnWidgetDestroying(views::Widget* widget) { |
314 BubbleDelegateView::OnWidgetDestroying(widget); | 383 BubbleDelegateView::OnWidgetDestroying(widget); |
315 if (delegate_ && widget == GetWidget()) | 384 if (delegate_ && widget == GetWidget()) |
316 delegate_->ViewClosing(); | 385 delegate_->ViewClosing(); |
317 } | 386 } |
318 | 387 |
319 void AppListView::OnWidgetActivationChanged(views::Widget* widget, | 388 void AppListView::OnWidgetActivationChanged(views::Widget* widget, |
320 bool active) { | 389 bool active) { |
(...skipping 14 matching lines...) Expand all Loading... |
335 // We clear the search when hiding so the next time the app list appears it is | 404 // We clear the search when hiding so the next time the app list appears it is |
336 // not showing search results. | 405 // not showing search results. |
337 if (!visible) | 406 if (!visible) |
338 app_list_main_view_->search_box_view()->ClearSearch(); | 407 app_list_main_view_->search_box_view()->ClearSearch(); |
339 | 408 |
340 // Whether we need to signin or not may have changed since last time we were | 409 // Whether we need to signin or not may have changed since last time we were |
341 // shown. | 410 // shown. |
342 Layout(); | 411 Layout(); |
343 } | 412 } |
344 | 413 |
| 414 void AppListView::OnSpeechRecognitionStateChanged( |
| 415 SpeechRecognitionState new_state) { |
| 416 DCHECK(!signin_view_->visible()); |
| 417 |
| 418 bool recognizing = new_state != SPEECH_RECOGNITION_NOT_STARTED; |
| 419 // No change for this class. |
| 420 if (speech_view_->visible() == recognizing) |
| 421 return; |
| 422 |
| 423 if (recognizing) |
| 424 speech_view_->Reset(); |
| 425 |
| 426 #if defined(USE_AURA) |
| 427 gfx::Transform speech_transform; |
| 428 speech_transform.Translate( |
| 429 0, SkFloatToMScalar(kSpeechUIApearingPosition)); |
| 430 if (recognizing) |
| 431 speech_view_->layer()->SetTransform(speech_transform); |
| 432 |
| 433 { |
| 434 ui::ScopedLayerAnimationSettings main_settings( |
| 435 app_list_main_view_->layer()->GetAnimator()); |
| 436 if (recognizing) { |
| 437 animation_observer_->SetTarget(app_list_main_view_); |
| 438 main_settings.AddObserver(animation_observer_.get()); |
| 439 } |
| 440 app_list_main_view_->layer()->SetOpacity(recognizing ? 0.0f : 1.0f); |
| 441 } |
| 442 |
| 443 { |
| 444 ui::ScopedLayerAnimationSettings speech_settings( |
| 445 speech_view_->layer()->GetAnimator()); |
| 446 if (!recognizing) { |
| 447 animation_observer_->SetTarget(speech_view_); |
| 448 speech_settings.AddObserver(animation_observer_.get()); |
| 449 } |
| 450 |
| 451 speech_view_->layer()->SetOpacity(recognizing ? 1.0f : 0.0f); |
| 452 if (recognizing) |
| 453 speech_view_->layer()->SetTransform(gfx::Transform()); |
| 454 else |
| 455 speech_view_->layer()->SetTransform(speech_transform); |
| 456 } |
| 457 |
| 458 if (recognizing) |
| 459 speech_view_->SetVisible(true); |
| 460 else |
| 461 app_list_main_view_->SetVisible(true); |
| 462 #else |
| 463 speech_view_->SetVisible(recognizing); |
| 464 app_list_main_view_->SetVisible(!recognizing); |
| 465 #endif |
| 466 |
| 467 // Needs to schedule paint of AppListView itself, to repaint the background. |
| 468 SchedulePaint(); |
| 469 } |
| 470 |
345 } // namespace app_list | 471 } // namespace app_list |
OLD | NEW |