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