status_area_overflow_button_tray.cc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // Copyright 2019 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. #include "ash/system/tray/status_area_overflow_button_tray.h"
  5. #include "ash/public/cpp/shelf_config.h"
  6. #include "ash/resources/vector_icons/vector_icons.h"
  7. #include "ash/shelf/shelf.h"
  8. #include "ash/strings/grit/ash_strings.h"
  9. #include "ash/system/status_area_widget.h"
  10. #include "ash/system/tray/tray_constants.h"
  11. #include "ash/system/tray/tray_container.h"
  12. #include "ui/compositor/layer.h"
  13. #include "ui/gfx/animation/slide_animation.h"
  14. #include "ui/gfx/animation/tween.h"
  15. #include "ui/gfx/paint_vector_icon.h"
  16. #include "ui/views/border.h"
  17. #include "ui/views/view.h"
  18. namespace ash {
  19. namespace {
  20. constexpr int kAnimationDurationMs = 250;
  21. constexpr int kTrayWidth = kStatusAreaOverflowButtonSize.width();
  22. constexpr int kTrayHeight = kStatusAreaOverflowButtonSize.height();
  23. } // namespace
  24. StatusAreaOverflowButtonTray::IconView::IconView()
  25. : slide_animation_(std::make_unique<gfx::SlideAnimation>(this)) {
  26. slide_animation_->Reset(1.0);
  27. slide_animation_->SetTweenType(gfx::Tween::EASE_OUT);
  28. slide_animation_->SetSlideDuration(base::Milliseconds(kAnimationDurationMs));
  29. SetPaintToLayer();
  30. layer()->SetFillsBoundsOpaquely(false);
  31. gfx::ImageSkia image = gfx::CreateVectorIcon(
  32. kOverflowShelfRightIcon,
  33. AshColorProvider::Get()->GetContentLayerColor(
  34. AshColorProvider::ContentLayerType::kIconColorPrimary));
  35. SetImage(image);
  36. const int vertical_padding = (kTrayHeight - image.height()) / 2;
  37. const int horizontal_padding = (kTrayWidth - image.width()) / 2;
  38. SetBorder(views::CreateEmptyBorder(
  39. gfx::Insets::VH(vertical_padding, horizontal_padding)));
  40. UpdateRotation();
  41. }
  42. StatusAreaOverflowButtonTray::IconView::~IconView() {}
  43. void StatusAreaOverflowButtonTray::IconView::ToggleState(State state) {
  44. slide_animation_->End();
  45. if (state == CLICK_TO_EXPAND)
  46. slide_animation_->Show();
  47. else if (state == CLICK_TO_COLLAPSE)
  48. slide_animation_->Hide();
  49. // TODO(tengs): Currently, the collpase/expand animation is not fully spec'd,
  50. // so skip it for now.
  51. slide_animation_->End();
  52. }
  53. void StatusAreaOverflowButtonTray::IconView::AnimationEnded(
  54. const gfx::Animation* animation) {
  55. UpdateRotation();
  56. }
  57. void StatusAreaOverflowButtonTray::IconView::AnimationProgressed(
  58. const gfx::Animation* animation) {
  59. UpdateRotation();
  60. }
  61. void StatusAreaOverflowButtonTray::IconView::AnimationCanceled(
  62. const gfx::Animation* animation) {
  63. UpdateRotation();
  64. }
  65. void StatusAreaOverflowButtonTray::IconView::UpdateRotation() {
  66. double progress = slide_animation_->GetCurrentValue();
  67. gfx::Transform transform;
  68. gfx::Vector2d center(kTrayWidth / 2.0, kTrayHeight / 2.0);
  69. transform.Translate(center);
  70. transform.RotateAboutZAxis(180.0 * progress);
  71. transform.Translate(gfx::Vector2d(-center.x(), -center.y()));
  72. SetTransform(transform);
  73. }
  74. StatusAreaOverflowButtonTray::StatusAreaOverflowButtonTray(Shelf* shelf)
  75. : TrayBackgroundView(shelf), icon_(new IconView()) {
  76. tray_container()->AddChildView(icon_);
  77. set_use_bounce_in_animation(false);
  78. }
  79. StatusAreaOverflowButtonTray::~StatusAreaOverflowButtonTray() {}
  80. void StatusAreaOverflowButtonTray::ClickedOutsideBubble() {}
  81. void StatusAreaOverflowButtonTray::ResetStateToCollapsed() {
  82. state_ = CLICK_TO_EXPAND;
  83. icon_->ToggleState(state_);
  84. }
  85. std::u16string StatusAreaOverflowButtonTray::GetAccessibleNameForTray() {
  86. return l10n_util::GetStringUTF16(
  87. state_ == CLICK_TO_COLLAPSE ? IDS_ASH_STATUS_AREA_OVERFLOW_BUTTON_COLLAPSE
  88. : IDS_ASH_STATUS_AREA_OVERFLOW_BUTTON_EXPAND);
  89. }
  90. void StatusAreaOverflowButtonTray::HandleLocaleChange() {}
  91. void StatusAreaOverflowButtonTray::HideBubbleWithView(
  92. const TrayBubbleView* bubble_view) {}
  93. void StatusAreaOverflowButtonTray::Initialize() {
  94. TrayBackgroundView::Initialize();
  95. SetVisiblePreferred(false);
  96. }
  97. bool StatusAreaOverflowButtonTray::PerformAction(const ui::Event& event) {
  98. state_ = state_ == CLICK_TO_COLLAPSE ? CLICK_TO_EXPAND : CLICK_TO_COLLAPSE;
  99. icon_->ToggleState(state_);
  100. shelf()->GetStatusAreaWidget()->UpdateCollapseState();
  101. return false;
  102. }
  103. void StatusAreaOverflowButtonTray::SetVisiblePreferred(bool visible_preferred) {
  104. // The visibility of the overflow tray button is completed controlled by the
  105. // StatusAreaWidget, so we bypass all default visibility logic from
  106. // TrayBackgroundView.
  107. views::View::SetVisible(visible_preferred);
  108. }
  109. void StatusAreaOverflowButtonTray::UpdateAfterStatusAreaCollapseChange() {
  110. // The visibility of the overflow tray button is completed controlled by the
  111. // StatusAreaWidget, so we bypass all default visibility logic from
  112. // TrayBackgroundView.
  113. }
  114. const char* StatusAreaOverflowButtonTray::GetClassName() const {
  115. return "StatusAreaOverflowButtonTray";
  116. }
  117. } // namespace ash