| 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 InitializeAndShowBubble(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 |