hover_highlight_view.cc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. // Copyright 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. #include "ash/system/tray/hover_highlight_view.h"
  5. #include <string>
  6. #include "ash/resources/vector_icons/vector_icons.h"
  7. #include "ash/strings/grit/ash_strings.h"
  8. #include "ash/style/ash_color_provider.h"
  9. #include "ash/system/tray/tray_constants.h"
  10. #include "ash/system/tray/tray_popup_utils.h"
  11. #include "ash/system/tray/tri_view.h"
  12. #include "ash/system/tray/unfocusable_label.h"
  13. #include "ash/system/tray/view_click_listener.h"
  14. #include "ui/accessibility/ax_enums.mojom.h"
  15. #include "ui/accessibility/ax_node_data.h"
  16. #include "ui/base/l10n/l10n_util.h"
  17. #include "ui/gfx/canvas.h"
  18. #include "ui/gfx/paint_vector_icon.h"
  19. #include "ui/views/animation/ink_drop.h"
  20. #include "ui/views/border.h"
  21. #include "ui/views/controls/image_view.h"
  22. #include "ui/views/controls/label.h"
  23. #include "ui/views/layout/box_layout.h"
  24. #include "ui/views/layout/fill_layout.h"
  25. #include "ui/views/view_utils.h"
  26. namespace ash {
  27. HoverHighlightView::HoverHighlightView(ViewClickListener* listener)
  28. : ActionableView(TrayPopupInkDropStyle::FILL_BOUNDS), listener_(listener) {
  29. SetNotifyEnterExitOnChild(true);
  30. views::InkDrop::Get(this)->SetMode(views::InkDropHost::InkDropMode::ON);
  31. }
  32. HoverHighlightView::~HoverHighlightView() = default;
  33. void HoverHighlightView::AddRightIcon(const gfx::ImageSkia& image,
  34. int icon_size) {
  35. DCHECK(is_populated_);
  36. DCHECK(!right_view_);
  37. views::ImageView* right_icon = TrayPopupUtils::CreateMainImageView();
  38. right_icon->SetImage(image);
  39. AddRightView(right_icon);
  40. }
  41. void HoverHighlightView::AddRightView(views::View* view,
  42. std::unique_ptr<views::Border> border) {
  43. DCHECK(is_populated_);
  44. DCHECK(!right_view_);
  45. // When a right view is added, extra padding on the CENTER container should be
  46. // removed.
  47. tri_view_->SetContainerBorder(TriView::Container::CENTER, nullptr);
  48. if (border)
  49. tri_view_->SetContainerBorder(TriView::Container::END, std::move(border));
  50. right_view_ = view;
  51. right_view_->SetEnabled(GetEnabled());
  52. tri_view_->AddView(TriView::Container::END, right_view_);
  53. tri_view_->SetContainerVisible(TriView::Container::END, true);
  54. }
  55. void HoverHighlightView::SetRightViewVisible(bool visible) {
  56. DCHECK(is_populated_);
  57. if (!right_view_)
  58. return;
  59. tri_view_->SetContainerVisible(TriView::Container::END, visible);
  60. right_view_->SetVisible(visible);
  61. Layout();
  62. }
  63. void HoverHighlightView::SetSubText(const std::u16string& sub_text) {
  64. DCHECK(sub_row_);
  65. DCHECK(!sub_text.empty());
  66. if (!sub_text_label_) {
  67. sub_text_label_ =
  68. sub_row_->AddChildView(TrayPopupUtils::CreateUnfocusableLabel());
  69. }
  70. sub_text_label_->SetEnabledColor(
  71. AshColorProvider::Get()->GetContentLayerColor(
  72. AshColorProvider::ContentLayerType::kTextColorSecondary));
  73. sub_text_label_->SetAutoColorReadabilityEnabled(false);
  74. sub_text_label_->SetText(sub_text);
  75. }
  76. void HoverHighlightView::AddIconAndLabel(const gfx::ImageSkia& image,
  77. const std::u16string& text) {
  78. DCHECK(!is_populated_);
  79. std::unique_ptr<views::ImageView> icon(TrayPopupUtils::CreateMainImageView());
  80. icon->SetImage(image);
  81. icon->SetEnabled(GetEnabled());
  82. AddViewAndLabel(std::move(icon), text);
  83. }
  84. void HoverHighlightView::AddViewAndLabel(std::unique_ptr<views::View> view,
  85. const std::u16string& text) {
  86. DCHECK(!is_populated_);
  87. DCHECK(view);
  88. is_populated_ = true;
  89. SetLayoutManager(std::make_unique<views::FillLayout>());
  90. tri_view_ = TrayPopupUtils::CreateDefaultRowView();
  91. AddChildView(tri_view_);
  92. left_view_ = view.get();
  93. tri_view_->AddView(TriView::Container::START, view.release());
  94. text_label_ = TrayPopupUtils::CreateUnfocusableLabel();
  95. text_label_->SetText(text);
  96. text_label_->SetEnabled(GetEnabled());
  97. text_label_->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor(
  98. AshColorProvider::ContentLayerType::kTextColorPrimary));
  99. TrayPopupUtils::SetLabelFontList(
  100. text_label_, TrayPopupUtils::FontStyle::kDetailedViewLabel);
  101. tri_view_->AddView(TriView::Container::CENTER, text_label_);
  102. // By default, END container is invisible, so labels in the CENTER should have
  103. // an extra padding at the end.
  104. tri_view_->SetContainerBorder(TriView::Container::CENTER,
  105. views::CreateEmptyBorder(gfx::Insets::TLBR(
  106. 0, 0, 0, kTrayPopupLabelRightPadding)));
  107. tri_view_->SetContainerVisible(TriView::Container::END, false);
  108. AddSubRowContainer();
  109. SetAccessibleName(text);
  110. }
  111. void HoverHighlightView::AddLabelRow(const std::u16string& text) {
  112. DCHECK(!is_populated_);
  113. is_populated_ = true;
  114. SetLayoutManager(std::make_unique<views::FillLayout>());
  115. tri_view_ = TrayPopupUtils::CreateDefaultRowView();
  116. AddChildView(tri_view_);
  117. text_label_ = TrayPopupUtils::CreateUnfocusableLabel();
  118. text_label_->SetText(text);
  119. text_label_->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor(
  120. AshColorProvider::ContentLayerType::kTextColorPrimary));
  121. TrayPopupUtils::SetLabelFontList(
  122. text_label_, TrayPopupUtils::FontStyle::kDetailedViewLabel);
  123. tri_view_->AddView(TriView::Container::CENTER, text_label_);
  124. AddSubRowContainer();
  125. SetAccessibleName(text);
  126. }
  127. void HoverHighlightView::AddLabelRow(const std::u16string& text,
  128. int start_inset) {
  129. AddLabelRow(text);
  130. tri_view_->SetMinSize(TriView::Container::START,
  131. gfx::Size(start_inset, kTrayPopupItemMinHeight));
  132. }
  133. void HoverHighlightView::SetExpandable(bool expandable) {
  134. if (expandable != expandable_) {
  135. expandable_ = expandable;
  136. InvalidateLayout();
  137. }
  138. }
  139. void HoverHighlightView::SetAccessibilityState(
  140. AccessibilityState accessibility_state) {
  141. accessibility_state_ = accessibility_state;
  142. if (accessibility_state_ != AccessibilityState::DEFAULT)
  143. NotifyAccessibilityEvent(ax::mojom::Event::kCheckedStateChanged, true);
  144. }
  145. void HoverHighlightView::Reset() {
  146. RemoveAllChildViews();
  147. text_label_ = nullptr;
  148. sub_text_label_ = nullptr;
  149. left_view_ = nullptr;
  150. right_view_ = nullptr;
  151. sub_row_ = nullptr;
  152. tri_view_ = nullptr;
  153. is_populated_ = false;
  154. }
  155. void HoverHighlightView::OnSetTooltipText(const std::u16string& tooltip_text) {
  156. if (text_label_)
  157. text_label_->SetTooltipText(tooltip_text);
  158. if (sub_text_label_)
  159. sub_text_label_->SetTooltipText(tooltip_text);
  160. if (left_view_) {
  161. DCHECK(views::IsViewClass<views::ImageView>(left_view_));
  162. static_cast<views::ImageView*>(left_view_)->SetTooltipText(tooltip_text);
  163. }
  164. }
  165. bool HoverHighlightView::PerformAction(const ui::Event& event) {
  166. if (!listener_)
  167. return false;
  168. listener_->OnViewClicked(this);
  169. return true;
  170. }
  171. void HoverHighlightView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
  172. if (right_view_ && right_view_->GetVisible() &&
  173. std::string(right_view_->GetClassName()).find("Button") !=
  174. std::string::npos) {
  175. // Allow selection of sub-components.
  176. node_data->role = ax::mojom::Role::kGenericContainer;
  177. // Include "press search plus space to activate" when announcing.
  178. node_data->SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kClick);
  179. node_data->SetName(GetAccessibleName());
  180. node_data->SetDescription(
  181. l10n_util::GetStringUTF16(IDS_ASH_A11Y_ROLE_BUTTON));
  182. } else {
  183. ActionableView::GetAccessibleNodeData(node_data);
  184. }
  185. ax::mojom::CheckedState checked_state;
  186. if (accessibility_state_ == AccessibilityState::CHECKED_CHECKBOX)
  187. checked_state = ax::mojom::CheckedState::kTrue;
  188. else if (accessibility_state_ == AccessibilityState::UNCHECKED_CHECKBOX)
  189. checked_state = ax::mojom::CheckedState::kFalse;
  190. else
  191. return; // Not a checkbox
  192. // Checkbox
  193. node_data->role = ax::mojom::Role::kCheckBox;
  194. node_data->SetCheckedState(checked_state);
  195. }
  196. const char* HoverHighlightView::GetClassName() const {
  197. return "HoverHighlightView";
  198. }
  199. gfx::Size HoverHighlightView::CalculatePreferredSize() const {
  200. gfx::Size size = ActionableView::CalculatePreferredSize();
  201. if (!expandable_ || size.height() < kTrayPopupItemMinHeight)
  202. size.set_height(kTrayPopupItemMinHeight);
  203. return size;
  204. }
  205. int HoverHighlightView::GetHeightForWidth(int width) const {
  206. return GetPreferredSize().height();
  207. }
  208. void HoverHighlightView::OnFocus() {
  209. ScrollRectToVisible(gfx::Rect(gfx::Point(), size()));
  210. ActionableView::OnFocus();
  211. }
  212. void HoverHighlightView::AddSubRowContainer() {
  213. DCHECK(is_populated_);
  214. DCHECK(tri_view_);
  215. DCHECK(text_label_);
  216. DCHECK(!sub_row_);
  217. sub_row_ = new views::View();
  218. sub_row_->SetLayoutManager(std::make_unique<views::BoxLayout>(
  219. views::BoxLayout::Orientation::kHorizontal));
  220. tri_view_->AddView(TriView::Container::CENTER, sub_row_);
  221. }
  222. void HoverHighlightView::OnEnabledChanged() {
  223. if (left_view_)
  224. left_view_->SetEnabled(GetEnabled());
  225. if (text_label_)
  226. text_label_->SetEnabled(GetEnabled());
  227. if (right_view_)
  228. right_view_->SetEnabled(GetEnabled());
  229. }
  230. } // namespace ash