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 3 // found in the LICENSE file. 4 5 #include "ash/system/tray/tray_item_view.h" 6 7 #include "ash/shelf/shelf_types.h" 8 #include "ash/system/tray/system_tray.h" 9 #include "ash/system/tray/system_tray_item.h" 10 #include "ui/compositor/layer.h" 11 #include "ui/gfx/animation/slide_animation.h" 12 #include "ui/views/controls/image_view.h" 13 #include "ui/views/controls/label.h" 14 #include "ui/views/layout/box_layout.h" 15 #include "ui/views/widget/widget.h" 16 17 namespace { 18 const int kTrayIconHeight = 29; 19 const int kTrayIconWidth = 29; 20 const int kTrayItemAnimationDurationMS = 200; 21 22 // Animations can be disabled for testing. 23 bool animations_enabled = true; 24 } 25 26 namespace ash { 27 namespace internal { 28 29 TrayItemView::TrayItemView(SystemTrayItem* owner) 30 : owner_(owner), 31 label_(NULL), 32 image_view_(NULL) { 33 SetPaintToLayer(true); 34 SetFillsBoundsOpaquely(false); 35 SetLayoutManager( 36 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0)); 37 } 38 39 TrayItemView::~TrayItemView() {} 40 41 // static 42 void TrayItemView::DisableAnimationsForTest() { 43 animations_enabled = false; 44 } 45 46 void TrayItemView::CreateLabel() { 47 label_ = new views::Label; 48 AddChildView(label_); 49 } 50 51 void TrayItemView::CreateImageView() { 52 image_view_ = new views::ImageView; 53 AddChildView(image_view_); 54 } 55 56 void TrayItemView::SetVisible(bool set_visible) { 57 if (!GetWidget() || !animations_enabled) { 58 views::View::SetVisible(set_visible); 59 return; 60 } 61 62 if (!animation_) { 63 animation_.reset(new gfx::SlideAnimation(this)); 64 animation_->SetSlideDuration(GetAnimationDurationMS()); 65 animation_->SetTweenType(gfx::Tween::LINEAR); 66 animation_->Reset(visible() ? 1.0 : 0.0); 67 } 68 69 if (!set_visible) { 70 animation_->Hide(); 71 AnimationProgressed(animation_.get()); 72 } else { 73 animation_->Show(); 74 AnimationProgressed(animation_.get()); 75 views::View::SetVisible(true); 76 } 77 } 78 79 gfx::Size TrayItemView::DesiredSize() { 80 return views::View::GetPreferredSize(); 81 } 82 83 int TrayItemView::GetAnimationDurationMS() { 84 return kTrayItemAnimationDurationMS; 85 } 86 87 gfx::Size TrayItemView::GetPreferredSize() { 88 gfx::Size size = DesiredSize(); 89 if (owner()->system_tray()->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM || 90 owner()->system_tray()->shelf_alignment() == SHELF_ALIGNMENT_TOP) 91 size.set_height(kTrayIconHeight); 92 else 93 size.set_width(kTrayIconWidth); 94 if (!animation_.get() || !animation_->is_animating()) 95 return size; 96 if (owner()->system_tray()->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM || 97 owner()->system_tray()->shelf_alignment() == SHELF_ALIGNMENT_TOP) { 98 size.set_width(std::max(1, 99 static_cast<int>(size.width() * animation_->GetCurrentValue()))); 100 } else { 101 size.set_height(std::max(1, 102 static_cast<int>(size.height() * animation_->GetCurrentValue()))); 103 } 104 return size; 105 } 106 107 int TrayItemView::GetHeightForWidth(int width) { 108 return GetPreferredSize().height(); 109 } 110 111 void TrayItemView::ChildPreferredSizeChanged(views::View* child) { 112 PreferredSizeChanged(); 113 } 114 115 void TrayItemView::AnimationProgressed(const gfx::Animation* animation) { 116 gfx::Transform transform; 117 if (owner()->system_tray()->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM || 118 owner()->system_tray()->shelf_alignment() == SHELF_ALIGNMENT_TOP) { 119 transform.Translate(0, animation->CurrentValueBetween( 120 static_cast<double>(height()) / 2, 0.)); 121 } else { 122 transform.Translate(animation->CurrentValueBetween( 123 static_cast<double>(width() / 2), 0.), 0); 124 } 125 transform.Scale(animation->GetCurrentValue(), 126 animation->GetCurrentValue()); 127 layer()->SetTransform(transform); 128 PreferredSizeChanged(); 129 } 130 131 void TrayItemView::AnimationEnded(const gfx::Animation* animation) { 132 if (animation->GetCurrentValue() < 0.1) 133 views::View::SetVisible(false); 134 } 135 136 void TrayItemView::AnimationCanceled(const gfx::Animation* animation) { 137 AnimationEnded(animation); 138 } 139 140 } // namespace internal 141 } // namespace ash 142