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/system/tray/system_tray_bubble.h" | 5 #include "ash/system/tray/system_tray_bubble.h" |
6 | 6 |
7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
8 #include "ash/system/tray/system_tray.h" | 8 #include "ash/system/tray/system_tray.h" |
9 #include "ash/system/tray/system_tray_delegate.h" | 9 #include "ash/system/tray/system_tray_delegate.h" |
10 #include "ash/system/tray/system_tray_item.h" | 10 #include "ash/system/tray/system_tray_item.h" |
11 #include "ash/system/tray/tray_constants.h" | 11 #include "ash/system/tray/tray_constants.h" |
12 #include "ash/wm/window_animations.h" | |
13 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
14 #include "ui/aura/window.h" | 13 #include "ui/aura/window.h" |
15 #include "ui/compositor/layer.h" | 14 #include "ui/compositor/layer.h" |
16 #include "ui/compositor/layer_animation_observer.h" | 15 #include "ui/compositor/layer_animation_observer.h" |
17 #include "ui/compositor/scoped_layer_animation_settings.h" | 16 #include "ui/compositor/scoped_layer_animation_settings.h" |
18 #include "ui/gfx/canvas.h" | 17 #include "ui/gfx/canvas.h" |
19 #include "ui/views/layout/box_layout.h" | 18 #include "ui/views/layout/box_layout.h" |
20 #include "ui/views/view.h" | 19 #include "ui/views/view.h" |
21 | 20 |
22 namespace ash { | 21 namespace ash { |
23 | 22 |
24 namespace { | 23 namespace { |
25 | 24 |
26 const int kAnimationDurationForPopupMS = 200; | |
27 | |
28 // Normally a detailed view is the same size as the default view. However, | 25 // Normally a detailed view is the same size as the default view. However, |
29 // when showing a detailed view directly (e.g. clicking on a notification), | 26 // when showing a detailed view directly (e.g. clicking on a notification), |
30 // we may not know the height of the default view, or the default view may | 27 // we may not know the height of the default view, or the default view may |
31 // be too short, so we use this as a default and minimum height for any | 28 // be too short, so we use this as a default and minimum height for any |
32 // detailed view. | 29 // detailed view. |
33 const int kDetailedBubbleMaxHeight = kTrayPopupItemHeight * 5; | 30 const int kDetailedBubbleMaxHeight = kTrayPopupItemHeight * 5; |
34 | 31 |
35 class TrayPopupItemBorder : public views::Border { | 32 class TrayPopupItemBorder : public views::Border { |
36 public: | 33 public: |
37 explicit TrayPopupItemBorder(views::View* owner) : owner_(owner) {} | 34 explicit TrayPopupItemBorder(views::View* owner) : owner_(owner) {} |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 private: | 148 private: |
152 scoped_ptr<ui::Layer> layer_; | 149 scoped_ptr<ui::Layer> layer_; |
153 | 150 |
154 DISALLOW_COPY_AND_ASSIGN(AnimationObserverDeleteLayer); | 151 DISALLOW_COPY_AND_ASSIGN(AnimationObserverDeleteLayer); |
155 }; | 152 }; |
156 | 153 |
157 } // namespace | 154 } // namespace |
158 | 155 |
159 namespace internal { | 156 namespace internal { |
160 | 157 |
161 // SystemTrayBubble::InitParams | |
162 SystemTrayBubble::InitParams::InitParams( | |
163 SystemTrayBubble::AnchorType anchor_type, | |
164 ShelfAlignment shelf_alignment) | |
165 : anchor(NULL), | |
166 anchor_type(anchor_type), | |
167 can_activate(false), | |
168 login_status(ash::user::LOGGED_IN_NONE), | |
169 arrow_offset(0), | |
170 max_height(0) { | |
171 } | |
172 | |
173 // SystemTrayBubble | 158 // SystemTrayBubble |
174 | 159 |
175 SystemTrayBubble::SystemTrayBubble( | 160 SystemTrayBubble::SystemTrayBubble( |
176 ash::SystemTray* tray, | 161 ash::SystemTray* tray, |
177 const std::vector<ash::SystemTrayItem*>& items, | 162 const std::vector<ash::SystemTrayItem*>& items, |
178 BubbleType bubble_type) | 163 BubbleType bubble_type) |
179 : tray_(tray), | 164 : tray_(tray), |
180 bubble_view_(NULL), | 165 bubble_view_(NULL), |
181 bubble_widget_(NULL), | 166 bubble_widget_(NULL), |
182 items_(items), | 167 items_(items), |
183 bubble_type_(bubble_type), | 168 bubble_type_(bubble_type), |
184 anchor_type_(ANCHOR_TYPE_TRAY), | |
185 autoclose_delay_(0) { | 169 autoclose_delay_(0) { |
186 } | 170 } |
187 | 171 |
188 SystemTrayBubble::~SystemTrayBubble() { | 172 SystemTrayBubble::~SystemTrayBubble() { |
189 DestroyItemViews(); | 173 DestroyItemViews(); |
190 // Reset the host pointer in bubble_view_ in case its destruction is deferred. | 174 // Reset the host pointer in bubble_view_ in case its destruction is deferred. |
191 if (bubble_view_) | 175 if (bubble_view_) |
192 bubble_view_->reset_host(); | 176 bubble_view_->reset_host(); |
193 if (bubble_widget_) { | 177 if (bubble_widget_) { |
194 bubble_widget_->RemoveObserver(this); | 178 bubble_widget_->RemoveObserver(this); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 { | 263 { |
280 ui::ScopedLayerAnimationSettings settings(new_layer->GetAnimator()); | 264 ui::ScopedLayerAnimationSettings settings(new_layer->GetAnimator()); |
281 settings.AddObserver(new AnimationObserverDeleteLayer(layer)); | 265 settings.AddObserver(new AnimationObserverDeleteLayer(layer)); |
282 settings.SetTransitionDuration(swipe_duration); | 266 settings.SetTransitionDuration(swipe_duration); |
283 settings.SetTweenType(ui::Tween::EASE_OUT); | 267 settings.SetTweenType(ui::Tween::EASE_OUT); |
284 new_layer->SetTransform(ui::Transform()); | 268 new_layer->SetTransform(ui::Transform()); |
285 } | 269 } |
286 } | 270 } |
287 } | 271 } |
288 | 272 |
289 void SystemTrayBubble::InitView(const InitParams& init_params) { | 273 void SystemTrayBubble::InitView(views::View* anchor, |
| 274 TrayBubbleView::InitParams init_params, |
| 275 user::LoginStatus login_status) { |
290 DCHECK(bubble_view_ == NULL); | 276 DCHECK(bubble_view_ == NULL); |
291 anchor_type_ = init_params.anchor_type; | 277 |
292 views::BubbleBorder::ArrowLocation arrow_location; | 278 if (bubble_type_ == BUBBLE_TYPE_DETAILED && |
293 if (anchor_type_ == ANCHOR_TYPE_TRAY) { | 279 init_params.max_height < kDetailedBubbleMaxHeight) { |
294 if (tray_->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM) { | 280 init_params.max_height = kDetailedBubbleMaxHeight; |
295 arrow_location = base::i18n::IsRTL() ? | |
296 views::BubbleBorder::BOTTOM_LEFT : | |
297 views::BubbleBorder::BOTTOM_RIGHT; | |
298 } else if (tray_->shelf_alignment() == SHELF_ALIGNMENT_LEFT) { | |
299 arrow_location = views::BubbleBorder::LEFT_BOTTOM; | |
300 } else { | |
301 arrow_location = views::BubbleBorder::RIGHT_BOTTOM; | |
302 } | |
303 } else { | |
304 arrow_location = views::BubbleBorder::NONE; | |
305 } | 281 } |
306 bubble_view_ = new TrayBubbleView( | 282 |
307 init_params.anchor, arrow_location, | 283 bubble_view_ = TrayBubbleView::Create(anchor, this, init_params); |
308 this, init_params.can_activate, kTrayPopupWidth); | 284 |
309 if (bubble_type_ == BUBBLE_TYPE_NOTIFICATION) | 285 if (bubble_type_ == BUBBLE_TYPE_NOTIFICATION) |
310 bubble_view_->set_close_on_deactivate(false); | 286 bubble_view_->set_close_on_deactivate(false); |
311 int max_height = init_params.max_height; | |
312 if (bubble_type_ == BUBBLE_TYPE_DETAILED && | |
313 max_height < kDetailedBubbleMaxHeight) | |
314 max_height = kDetailedBubbleMaxHeight; | |
315 bubble_view_->SetMaxHeight(max_height); | |
316 | 287 |
317 CreateItemViews(init_params.login_status); | 288 CreateItemViews(login_status); |
318 | 289 |
319 DCHECK(bubble_widget_ == NULL); | 290 DCHECK(bubble_widget_ == NULL); |
320 bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_); | 291 bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_); |
321 | |
322 // Must occur after call to CreateBubble() | |
323 bubble_view_->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); | |
324 bubble_widget_->non_client_view()->frame_view()->set_background(NULL); | |
325 bubble_view_->SetBubbleBorder(init_params.arrow_offset); | |
326 | |
327 bubble_widget_->AddObserver(this); | 292 bubble_widget_->AddObserver(this); |
328 | 293 |
329 // Setup animation. | 294 PostCreateBubble(bubble_widget_, bubble_view_, tray_); |
330 ash::SetWindowVisibilityAnimationType( | |
331 bubble_widget_->GetNativeWindow(), | |
332 ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); | |
333 ash::SetWindowVisibilityAnimationTransition( | |
334 bubble_widget_->GetNativeWindow(), | |
335 ash::ANIMATE_BOTH); | |
336 ash::SetWindowVisibilityAnimationDuration( | |
337 bubble_widget_->GetNativeWindow(), | |
338 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS)); | |
339 | |
340 InitializeHost(bubble_widget_, tray_); | |
341 | |
342 bubble_view_->Show(); | |
343 } | 295 } |
344 | 296 |
345 void SystemTrayBubble::BubbleViewDestroyed() { | 297 void SystemTrayBubble::BubbleViewDestroyed() { |
346 DestroyItemViews(); | 298 DestroyItemViews(); |
347 bubble_view_ = NULL; | 299 bubble_view_ = NULL; |
348 } | 300 } |
349 | 301 |
350 gfx::Rect SystemTrayBubble::GetAnchorRect() const { | |
351 gfx::Rect rect; | |
352 views::Widget* widget = bubble_view()->anchor_widget(); | |
353 if (widget->IsVisible()) { | |
354 rect = widget->GetWindowBoundsInScreen(); | |
355 if (anchor_type_ == ANCHOR_TYPE_TRAY) { | |
356 if (tray_->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM) { | |
357 rect.Inset( | |
358 base::i18n::IsRTL() ? | |
359 kPaddingFromRightEdgeOfScreenBottomAlignment : 0, | |
360 0, | |
361 base::i18n::IsRTL() ? | |
362 0 : kPaddingFromRightEdgeOfScreenBottomAlignment, | |
363 kPaddingFromBottomOfScreenBottomAlignment); | |
364 } else if (tray_->shelf_alignment() == SHELF_ALIGNMENT_LEFT) { | |
365 rect.Inset(0, 0, kPaddingFromInnerEdgeOfLauncherVerticalAlignment, | |
366 kPaddingFromBottomOfScreenVerticalAlignment); | |
367 } else { | |
368 rect.Inset(kPaddingFromInnerEdgeOfLauncherVerticalAlignment, | |
369 0, 0, kPaddingFromBottomOfScreenVerticalAlignment); | |
370 } | |
371 } else if (anchor_type_ == ANCHOR_TYPE_BUBBLE) { | |
372 // For notification bubble to be anchored with uber tray bubble, | |
373 // the anchor can include arrow on left or right, which should | |
374 // be deducted out from the anchor rect. | |
375 views::View* anchor_view = bubble_view()->anchor_view(); | |
376 rect = anchor_view->GetBoundsInScreen(); | |
377 gfx::Insets insets = anchor_view->GetInsets(); | |
378 rect.Inset(insets); | |
379 } | |
380 } | |
381 return rect; | |
382 } | |
383 | |
384 void SystemTrayBubble::OnMouseEnteredView() { | 302 void SystemTrayBubble::OnMouseEnteredView() { |
385 StopAutoCloseTimer(); | 303 StopAutoCloseTimer(); |
386 } | 304 } |
387 | 305 |
388 void SystemTrayBubble::OnMouseExitedView() { | 306 void SystemTrayBubble::OnMouseExitedView() { |
389 RestartAutoCloseTimer(); | 307 RestartAutoCloseTimer(); |
390 } | 308 } |
391 | 309 |
392 void SystemTrayBubble::OnClickedOutsideView() { | 310 void SystemTrayBubble::OnClickedOutsideView() { |
393 if (bubble_type_ != BUBBLE_TYPE_NOTIFICATION) | 311 if (bubble_type_ != BUBBLE_TYPE_NOTIFICATION) |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 } | 391 } |
474 | 392 |
475 void SystemTrayBubble::OnWidgetClosing(views::Widget* widget) { | 393 void SystemTrayBubble::OnWidgetClosing(views::Widget* widget) { |
476 CHECK_EQ(bubble_widget_, widget); | 394 CHECK_EQ(bubble_widget_, widget); |
477 bubble_widget_ = NULL; | 395 bubble_widget_ = NULL; |
478 tray_->RemoveBubble(this); | 396 tray_->RemoveBubble(this); |
479 } | 397 } |
480 | 398 |
481 } // namespace internal | 399 } // namespace internal |
482 } // namespace ash | 400 } // namespace ash |
OLD | NEW |