summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-24 03:28:04 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-24 03:28:04 +0000
commit8ffd3e8220b1a7536fa506d17a4941c82fdde41a (patch)
tree14b98e159a7462fa10812bd59ba081a495beef1f /ash
parentd94361506fc6d10a85e1de864a9769ac1924c5ed (diff)
downloadchromium_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.cc171
-rw-r--r--ash/system/tray/system_tray_bubble.h10
-rw-r--r--ash/system/tray/tray_views.cc32
-rw-r--r--ash/system/tray/tray_views.h3
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_;