channel_indicator.cc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // Copyright (c) 2022 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/channel_indicator/channel_indicator.h"
  5. #include "ash/resources/vector_icons/vector_icons.h"
  6. #include "ash/session/session_controller_impl.h"
  7. #include "ash/shelf/shelf.h"
  8. #include "ash/shell.h"
  9. #include "ash/system/channel_indicator/channel_indicator_utils.h"
  10. #include "ash/system/tray/tray_constants.h"
  11. #include "base/memory/weak_ptr.h"
  12. #include "base/strings/strcat.h"
  13. #include "base/strings/string_util.h"
  14. #include "components/session_manager/session_manager_types.h"
  15. #include "components/version_info/channel.h"
  16. #include "ui/accessibility/ax_node_data.h"
  17. #include "ui/base/l10n/l10n_util.h"
  18. #include "ui/gfx/geometry/rect.h"
  19. #include "ui/gfx/geometry/size.h"
  20. #include "ui/gfx/paint_vector_icon.h"
  21. #include "ui/views/background.h"
  22. #include "ui/views/border.h"
  23. #include "ui/views/controls/image_view.h"
  24. #include "ui/views/layout/box_layout.h"
  25. #include "ui/views/view.h"
  26. namespace ash {
  27. namespace {
  28. // Background rounded rectangle corner radius.
  29. constexpr int kIndicatorBgCornerRadius = 50;
  30. // Size of padding area around the icon or text.
  31. constexpr int kIndicatorInset = 8;
  32. } // namespace
  33. ChannelIndicatorView::ChannelIndicatorView(Shelf* shelf,
  34. version_info::Channel channel)
  35. : TrayItemView(shelf), channel_(channel), session_observer_(this) {
  36. shell_observer_.Observe(Shell::Get());
  37. SetVisible(false);
  38. Update();
  39. }
  40. ChannelIndicatorView::~ChannelIndicatorView() = default;
  41. void ChannelIndicatorView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
  42. node_data->SetName(accessible_name_);
  43. }
  44. views::View* ChannelIndicatorView::GetTooltipHandlerForPoint(
  45. const gfx::Point& point) {
  46. return GetLocalBounds().Contains(point) ? this : nullptr;
  47. }
  48. std::u16string ChannelIndicatorView::GetTooltipText(const gfx::Point& p) const {
  49. return tooltip_;
  50. }
  51. const char* ChannelIndicatorView::GetClassName() const {
  52. return "ChannelIndicatorView";
  53. }
  54. void ChannelIndicatorView::OnThemeChanged() {
  55. TrayItemView::OnThemeChanged();
  56. if (Shell::Get()->session_controller()->GetSessionState() ==
  57. session_manager::SessionState::ACTIVE) {
  58. // User is logged in, set image view colors.
  59. if (image_view()) {
  60. image_view()->SetBackground(views::CreateRoundedRectBackground(
  61. channel_indicator_utils::GetBgColor(channel_),
  62. kIndicatorBgCornerRadius));
  63. image_view()->SetImage(gfx::CreateVectorIcon(
  64. channel_indicator_utils::GetVectorIcon(channel_),
  65. kUnifiedTrayChannelIndicatorDimension,
  66. channel_indicator_utils::GetFgColor(channel_)));
  67. }
  68. return;
  69. }
  70. // User is not logged in, set label colors.
  71. if (label()) {
  72. label()->SetBackground(views::CreateRoundedRectBackground(
  73. channel_indicator_utils::GetBgColor(channel_),
  74. kIndicatorBgCornerRadius));
  75. label()->SetEnabledColor(channel_indicator_utils::GetFgColor(channel_));
  76. }
  77. }
  78. void ChannelIndicatorView::HandleLocaleChange() {
  79. Update();
  80. }
  81. void ChannelIndicatorView::Update() {
  82. if (!channel_indicator_utils::IsDisplayableChannel(channel_))
  83. return;
  84. SetImageOrText();
  85. SetVisible(true);
  86. SetAccessibleName();
  87. SetTooltip();
  88. }
  89. void ChannelIndicatorView::SetImageOrText() {
  90. DCHECK(channel_indicator_utils::IsDisplayableChannel(channel_));
  91. if (Shell::Get()->session_controller()->GetSessionState() ==
  92. session_manager::SessionState::ACTIVE) {
  93. // User is logged in, show the icon.
  94. if (image_view())
  95. return;
  96. DestroyLabel();
  97. CreateImageView();
  98. // Border insets depend on shelf horizontal alignment.
  99. SetBorder(views::CreateEmptyBorder(
  100. IsHorizontalAlignment() ? gfx::Insets::VH(kIndicatorInset, 0)
  101. : gfx::Insets::VH(0, kIndicatorInset)));
  102. image_view()->SetBackground(views::CreateRoundedRectBackground(
  103. channel_indicator_utils::GetBgColor(channel_),
  104. kIndicatorBgCornerRadius));
  105. image_view()->SetImage(
  106. gfx::CreateVectorIcon(channel_indicator_utils::GetVectorIcon(channel_),
  107. kUnifiedTrayChannelIndicatorDimension,
  108. channel_indicator_utils::GetFgColor(channel_)));
  109. PreferredSizeChanged();
  110. return;
  111. }
  112. // User is not logged in, show the channel name.
  113. if (label())
  114. return;
  115. DestroyImageView();
  116. CreateLabel();
  117. // Label is only displayed if the user is in a non-active `SessionState`,
  118. // where side-shelf isn't possible (for now at least!), so nothing here is
  119. // adjusted for shelf alignment.
  120. DCHECK(IsHorizontalAlignment());
  121. SetBorder(views::CreateEmptyBorder(gfx::Insets::VH(kIndicatorInset, 0)));
  122. label()->SetBorder(views::CreateEmptyBorder(gfx::Insets::VH(0, 6)));
  123. label()->SetBackground(views::CreateRoundedRectBackground(
  124. channel_indicator_utils::GetBgColor(channel_), kIndicatorBgCornerRadius));
  125. label()->SetEnabledColor(channel_indicator_utils::GetFgColor(channel_));
  126. label()->SetText(l10n_util::GetStringUTF16(
  127. channel_indicator_utils::GetChannelNameStringResourceID(
  128. channel_,
  129. /*append_channel=*/false)));
  130. PreferredSizeChanged();
  131. }
  132. void ChannelIndicatorView::SetAccessibleName() {
  133. DCHECK(channel_indicator_utils::IsDisplayableChannel(channel_));
  134. accessible_name_ = l10n_util::GetStringUTF16(
  135. channel_indicator_utils::GetChannelNameStringResourceID(
  136. channel_, /*append_channel=*/true));
  137. // If icon is showing, set it on the image view.
  138. if (image_view()) {
  139. DCHECK(!label());
  140. image_view()->SetAccessibleName(accessible_name_);
  141. return;
  142. }
  143. // Otherwise set it on the label.
  144. if (label())
  145. label()->SetAccessibleName(accessible_name_);
  146. }
  147. void ChannelIndicatorView::SetTooltip() {
  148. DCHECK(channel_indicator_utils::IsDisplayableChannel(channel_));
  149. tooltip_ = l10n_util::GetStringUTF16(
  150. channel_indicator_utils::GetChannelNameStringResourceID(
  151. channel_, /*append_channel=*/true));
  152. }
  153. void ChannelIndicatorView::OnSessionStateChanged(
  154. session_manager::SessionState state) {
  155. Update();
  156. }
  157. void ChannelIndicatorView::OnShelfAlignmentChanged(
  158. aura::Window* root_window,
  159. ShelfAlignment old_alignment) {
  160. if (image_view()) {
  161. // Border insets depend on shelf horizontal alignment.
  162. SetBorder(views::CreateEmptyBorder(
  163. IsHorizontalAlignment() ? gfx::Insets::VH(kIndicatorInset, 0)
  164. : gfx::Insets::VH(0, kIndicatorInset)));
  165. }
  166. }
  167. bool ChannelIndicatorView::IsLabelVisibleForTesting() {
  168. return label() && label()->GetVisible();
  169. }
  170. bool ChannelIndicatorView::IsImageViewVisibleForTesting() {
  171. return image_view() && image_view()->GetVisible();
  172. }
  173. std::u16string ChannelIndicatorView::GetAccessibleNameString() const {
  174. if (image_view())
  175. return image_view()->GetAccessibleName();
  176. if (label())
  177. return label()->GetAccessibleName();
  178. return base::EmptyString16();
  179. }
  180. } // namespace ash