diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-24 03:28:04 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-24 03:28:04 +0000 |
commit | 8ffd3e8220b1a7536fa506d17a4941c82fdde41a (patch) | |
tree | 14b98e159a7462fa10812bd59ba081a495beef1f /ash | |
parent | d94361506fc6d10a85e1de864a9769ac1924c5ed (diff) | |
download | chromium_src-8ffd3e8220b1a7536fa506d17a4941c82fdde41a.zip chromium_src-8ffd3e8220b1a7536fa506d17a4941c82fdde41a.tar.gz chromium_src-8ffd3e8220b1a7536fa506d17a4941c82fdde41a.tar.bz2 |
ash: Add some slide animation for the uber tray popups.
BUG=127430, 124587
TEST=none
Review URL: https://chromiumcodereview.appspot.com/10399101
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138722 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r-- | ash/system/tray/system_tray_bubble.cc | 171 | ||||
-rw-r--r-- | ash/system/tray/system_tray_bubble.h | 10 | ||||
-rw-r--r-- | ash/system/tray/tray_views.cc | 32 | ||||
-rw-r--r-- | ash/system/tray/tray_views.h | 3 |
4 files changed, 148 insertions, 68 deletions
diff --git a/ash/system/tray/system_tray_bubble.cc b/ash/system/tray/system_tray_bubble.cc index e4787aa..8a053d0 100644 --- a/ash/system/tray/system_tray_bubble.cc +++ b/ash/system/tray/system_tray_bubble.cc @@ -22,6 +22,8 @@ #include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/l10n/l10n_util.h" #include "ui/compositor/layer.h" +#include "ui/compositor/layer_animation_observer.h" +#include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/gfx/canvas.h" #include "ui/gfx/screen.h" #include "ui/views/bubble/bubble_frame_view.h" @@ -90,8 +92,11 @@ class TrayPopupItemContainer : public views::View { explicit TrayPopupItemContainer(views::View* view) : hover_(false) { set_notify_enter_exit_on_child(true); set_border(view->border() ? views::Border::CreateEmptyBorder(0, 0, 0, 0) : - NULL); - SetLayoutManager(new views::FillLayout); + views::Border::CreateSolidSidedBorder(1, 1, 0, 1, kBorderDarkColor)); + views::BoxLayout* layout = new views::BoxLayout( + views::BoxLayout::kVertical, 0, 0, 0); + layout->set_spread_blank_space(true); + SetLayoutManager(layout); SetPaintToLayer(view->layer() != NULL); if (view->layer()) SetFillsBoundsOpaquely(view->layer()->fills_bounds_opaquely()); @@ -155,39 +160,6 @@ class SystemTrayBubbleBorder : public views::BubbleBorder { virtual ~SystemTrayBubbleBorder() {} private: - void PaintChildBorder(gfx::Canvas* canvas) const { - gfx::Insets insets; - GetInsets(&insets); - canvas->Save(); - canvas->Translate(gfx::Point(insets.left(), insets.top())); - views::View* last_view = NULL; - for (int i = 0; i < owner_->child_count(); i++) { - views::View* v = owner_->child_at(i); - if (!v->visible()) - continue; - - if (!v->border()) { - canvas->DrawLine(gfx::Point(v->x(), v->y() - 1), - gfx::Point(v->x() + v->width(), v->y() - 1), - !last_view || last_view->border() ? kBorderDarkColor : - kBorderLightColor); - } else if (last_view && !last_view->border()) { - canvas->DrawLine(gfx::Point(v->x() - 1, v->y() - 1), - gfx::Point(v->x() + v->width() + 1, v->y() - 1), - kBorderDarkColor); - } - - canvas->DrawLine(gfx::Point(v->x() - 1, v->y() - 1), - gfx::Point(v->x() - 1, v->y() + v->height() + 1), - kBorderDarkColor); - canvas->DrawLine(gfx::Point(v->x() + v->width(), v->y() - 1), - gfx::Point(v->x() + v->width(), v->y() + v->height() + 1), - kBorderDarkColor); - last_view = v; - } - canvas->Restore(); - } - // Overridden from views::BubbleBorder. // Override views::BubbleBorder to set the bubble on top of the anchor when // it has no arrow. @@ -220,8 +192,6 @@ class SystemTrayBubbleBorder : public views::BubbleBorder { DrawBlurredShadowAroundView(canvas, 0, owner_->height(), owner_->width(), inset); - PaintChildBorder(canvas); - // Draw the bottom line. int y = owner_->height() + 1; canvas->FillRect(gfx::Rect(inset.left(), y, owner_->width(), @@ -288,6 +258,27 @@ class SystemTrayBubbleBorder : public views::BubbleBorder { DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleBorder); }; +// Implicit animation observer that deletes itself and the layer at the end of +// the animation. +class AnimationObserverDeleteLayer : public ui::ImplicitAnimationObserver { + public: + explicit AnimationObserverDeleteLayer(ui::Layer* layer) + : layer_(layer) { + } + + virtual ~AnimationObserverDeleteLayer() { + } + + virtual void OnImplicitAnimationsCompleted() OVERRIDE { + MessageLoopForUI::current()->DeleteSoon(FROM_HERE, this); + } + + private: + scoped_ptr<ui::Layer> layer_; + + DISALLOW_COPY_AND_ASSIGN(AnimationObserverDeleteLayer); +}; + } // namespace namespace internal { @@ -307,6 +298,8 @@ SystemTrayBubbleView::SystemTrayBubbleView( set_parent_window(ash::Shell::GetInstance()->GetContainer( ash::internal::kShellWindowId_SettingBubbleContainer)); set_notify_enter_exit_on_child(true); + SetPaintToLayer(true); + SetFillsBoundsOpaquely(true); } SystemTrayBubbleView::~SystemTrayBubbleView() { @@ -326,10 +319,7 @@ void SystemTrayBubbleView::UpdateAnchor() { void SystemTrayBubbleView::Init() { views::BoxLayout* layout = - new views::BoxLayout(views::BoxLayout::kVertical, - kSystemTrayBubbleHorizontalInset, - kSystemTrayBubbleVerticalInset, - 1); + new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0); layout->set_spread_blank_space(true); SetLayoutManager(layout); set_background(NULL); @@ -351,18 +341,6 @@ gfx::Rect SystemTrayBubbleView::GetAnchorRect() { return rect; } -void SystemTrayBubbleView::ChildPreferredSizeChanged(View* child) { - SizeToContents(); -} - -void SystemTrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) { - if (can_activate_) { - state->role = ui::AccessibilityTypes::ROLE_WINDOW; - state->name = l10n_util::GetStringUTF16( - IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); - } -} - bool SystemTrayBubbleView::CanActivate() const { return can_activate_; } @@ -385,6 +363,28 @@ void SystemTrayBubbleView::OnMouseExited(const views::MouseEvent& event) { host_->RestartAutoCloseTimer(); } +void SystemTrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) { + if (can_activate_) { + state->role = ui::AccessibilityTypes::ROLE_WINDOW; + state->name = l10n_util::GetStringUTF16( + IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); + } +} + +void SystemTrayBubbleView::ChildPreferredSizeChanged(View* child) { + SizeToContents(); +} + +void SystemTrayBubbleView::ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child) { + if (is_add && child == this) { + parent->SetPaintToLayer(true); + parent->SetFillsBoundsOpaquely(true); + parent->layer()->SetMasksToBounds(true); + } +} + // SystemTrayBubble::InitParams SystemTrayBubble::InitParams::InitParams( SystemTrayBubble::AnchorType anchor_type, @@ -434,6 +434,54 @@ SystemTrayBubble::~SystemTrayBubble() { void SystemTrayBubble::UpdateView( const std::vector<ash::SystemTrayItem*>& items, BubbleType bubble_type) { + DCHECK(bubble_type != BUBBLE_TYPE_NOTIFICATION); + DCHECK(bubble_type != bubble_type_); + + const int kSwipeDelayMS = 300; + base::TimeDelta swipe_duration = + base::TimeDelta::FromMilliseconds(kSwipeDelayMS); + ui::Layer* layer = bubble_view_->RecreateLayer(); + layer->SuppressPaint(); + + // When transitioning from detailed view to default view, animate the existing + // view (slide out towards the right). + if (bubble_type == BUBBLE_TYPE_DEFAULT) { + // Make sure the old view is visibile over the new view during the + // animation. + layer->parent()->StackAbove(layer, bubble_view_->layer()); + ui::ScopedLayerAnimationSettings settings(layer->GetAnimator()); + settings.AddObserver(new AnimationObserverDeleteLayer(layer)); + settings.SetTransitionDuration(swipe_duration); + settings.SetTweenType(ui::Tween::EASE_IN); + ui::Transform transform; + transform.SetTranslateX(layer->bounds().width()); + layer->SetTransform(transform); + } + + { + // Add a shadow layer to make the old layer darker as the animation + // progresses. + ui::Layer* shadow = new ui::Layer(ui::LAYER_SOLID_COLOR); + shadow->SetColor(SK_ColorBLACK); + shadow->SetOpacity(0.01f); + shadow->SetBounds(layer->bounds()); + layer->Add(shadow); + layer->StackAtTop(shadow); + { + // Animate the darkening effect a little longer than the swipe-in. This is + // to make sure the darkening animation does not end up finishing early, + // because the dark layer goes away at the end of the animation, and there + // is a brief moment when the old view is still visible, but it does not + // have the shadow layer on top. + ui::ScopedLayerAnimationSettings settings(shadow->GetAnimator()); + settings.AddObserver(new AnimationObserverDeleteLayer(shadow)); + settings.SetTransitionDuration(swipe_duration + + base::TimeDelta::FromMilliseconds(150)); + settings.SetTweenType(ui::Tween::LINEAR); + shadow->SetOpacity(0.15f); + } + } + DestroyItemViews(); bubble_view_->RemoveAllChildViews(true); @@ -446,6 +494,23 @@ void SystemTrayBubble::UpdateView( bubble_view_->set_max_height(0); // Clear max height limit. bubble_view_->SizeToContents(); } + + // When transitioning from default view to detailed view, animate the new + // view (slide in from the right). + if (bubble_type == BUBBLE_TYPE_DETAILED) { + ui::Layer* new_layer = bubble_view_->layer(); + gfx::Rect bounds = new_layer->bounds(); + ui::Transform transform; + transform.SetTranslateX(bounds.width()); + new_layer->SetTransform(transform); + { + ui::ScopedLayerAnimationSettings settings(new_layer->GetAnimator()); + settings.AddObserver(new AnimationObserverDeleteLayer(layer)); + settings.SetTransitionDuration(swipe_duration); + settings.SetTweenType(ui::Tween::EASE_IN); + new_layer->SetTransform(ui::Transform()); + } + } } void SystemTrayBubble::InitView(const InitParams& init_params) { diff --git a/ash/system/tray/system_tray_bubble.h b/ash/system/tray/system_tray_bubble.h index d26c592..5194ad6 100644 --- a/ash/system/tray/system_tray_bubble.h +++ b/ash/system/tray/system_tray_bubble.h @@ -46,13 +46,17 @@ class SystemTrayBubbleView : public views::BubbleDelegateView { // Overridden from views::BubbleDelegateView. virtual void Init() OVERRIDE; virtual gfx::Rect GetAnchorRect() OVERRIDE; - // Overridden from views::View. - virtual void ChildPreferredSizeChanged(View* child) OVERRIDE; - virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; virtual bool CanActivate() const OVERRIDE; + + // Overridden from views::View. virtual gfx::Size GetPreferredSize() OVERRIDE; virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE; virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; + virtual void ChildPreferredSizeChanged(View* child) OVERRIDE; + virtual void ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child) OVERRIDE; void set_max_height(int height) { max_height_ = height; } diff --git a/ash/system/tray/tray_views.cc b/ash/system/tray/tray_views.cc index 6ce432f..baee946 100644 --- a/ash/system/tray/tray_views.cc +++ b/ash/system/tray/tray_views.cc @@ -368,6 +368,9 @@ void TrayPopupHeaderButton::StateChanged() { SchedulePaint(); } +//////////////////////////////////////////////////////////////////////////////// +// SpecialPopupRow + SpecialPopupRow::SpecialPopupRow() : content_(NULL), button_container_(NULL) { @@ -421,6 +424,13 @@ void SpecialPopupRow::AddButton(TrayPopupHeaderButton* button) { button_container_->AddChildView(button); } +gfx::Size SpecialPopupRow::GetPreferredSize() { + const int kFixedHeight = 55; + gfx::Size size = views::View::GetPreferredSize(); + size.set_height(kFixedHeight); + return size; +} + void SpecialPopupRow::Layout() { views::View::Layout(); gfx::Rect content_bounds = GetContentsBounds(); @@ -442,17 +452,6 @@ void SpecialPopupRow::Layout() { content_->SetBoundsRect(bounds); } -void SetupLabelForTray(views::Label* label) { - label->SetFont( - label->font().DeriveFont(2, gfx::Font::BOLD)); - label->SetAutoColorReadabilityEnabled(false); - label->SetEnabledColor(SK_ColorWHITE); - label->SetBackgroundColor(SkColorSetARGB(0, 255, 255, 255)); - label->SetShadowColors(SkColorSetARGB(64, 0, 0, 0), - SkColorSetARGB(64, 0, 0, 0)); - label->SetShadowOffset(0, 1); -} - //////////////////////////////////////////////////////////////////////////////// // TrayNotificationView @@ -496,5 +495,16 @@ void TrayNotificationView::ButtonPressed(views::Button* sender, OnClose(); } +void SetupLabelForTray(views::Label* label) { + label->SetFont( + label->font().DeriveFont(2, gfx::Font::BOLD)); + label->SetAutoColorReadabilityEnabled(false); + label->SetEnabledColor(SK_ColorWHITE); + label->SetBackgroundColor(SkColorSetARGB(0, 255, 255, 255)); + label->SetShadowColors(SkColorSetARGB(64, 0, 0, 0), + SkColorSetARGB(64, 0, 0, 0)); + label->SetShadowOffset(0, 1); +} + } // namespace internal } // namespace ash diff --git a/ash/system/tray/tray_views.h b/ash/system/tray/tray_views.h index 7a6f180..0afebcf 100644 --- a/ash/system/tray/tray_views.h +++ b/ash/system/tray/tray_views.h @@ -218,7 +218,7 @@ class TrayPopupHeaderButton : public views::ToggleImageButton { }; // The 'special' looking row in the uber-tray popups. This is usually the bottom -// row in the popups. +// row in the popups, and has a fixed height. class SpecialPopupRow : public views::View { public: SpecialPopupRow(); @@ -233,6 +233,7 @@ class SpecialPopupRow : public views::View { private: // Overridden from views::View. + virtual gfx::Size GetPreferredSize() OVERRIDE; virtual void Layout() OVERRIDE; views::View* content_; |