continue_browsing_chip.cc 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // Copyright 2020 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/phonehub/continue_browsing_chip.h"
  5. #include "ash/components/multidevice/logging/logging.h"
  6. #include "ash/components/phonehub/user_action_recorder.h"
  7. #include "ash/public/cpp/new_window_delegate.h"
  8. #include "ash/resources/vector_icons/vector_icons.h"
  9. #include "ash/root_window_controller.h"
  10. #include "ash/shell.h"
  11. #include "ash/strings/grit/ash_strings.h"
  12. #include "ash/style/ash_color_provider.h"
  13. #include "ash/system/phonehub/phone_hub_metrics.h"
  14. #include "ash/system/phonehub/phone_hub_tray.h"
  15. #include "ash/system/status_area_widget.h"
  16. #include "base/bind.h"
  17. #include "base/strings/string_number_conversions.h"
  18. #include "base/strings/utf_string_conversions.h"
  19. #include "ui/base/l10n/l10n_util.h"
  20. #include "ui/color/color_id.h"
  21. #include "ui/gfx/paint_vector_icon.h"
  22. #include "ui/views/controls/focus_ring.h"
  23. #include "ui/views/controls/highlight_path_generator.h"
  24. #include "ui/views/controls/image_view.h"
  25. #include "ui/views/controls/label.h"
  26. #include "ui/views/layout/box_layout.h"
  27. namespace ash {
  28. namespace {
  29. // Appearance in dip.
  30. constexpr gfx::Insets kContinueBrowsingChipInsets(8);
  31. constexpr int kContinueBrowsingChipSpacing = 8;
  32. constexpr int kContinueBrowsingChipFaviconSpacing = 8;
  33. constexpr gfx::Size kContinueBrowsingChipFaviconSize(16, 16);
  34. constexpr int kTaskContinuationChipRadius = 8;
  35. constexpr int kTitleMaxLines = 2;
  36. } // namespace
  37. ContinueBrowsingChip::ContinueBrowsingChip(
  38. const phonehub::BrowserTabsModel::BrowserTabMetadata& metadata,
  39. int index,
  40. size_t total_count,
  41. phonehub::UserActionRecorder* user_action_recorder)
  42. : views::Button(base::BindRepeating(&ContinueBrowsingChip::ButtonPressed,
  43. base::Unretained(this))),
  44. url_(metadata.url),
  45. index_(index),
  46. total_count_(total_count),
  47. user_action_recorder_(user_action_recorder) {
  48. auto* color_provider = AshColorProvider::Get();
  49. SetFocusBehavior(FocusBehavior::ALWAYS);
  50. views::FocusRing::Get(this)->SetColorId(ui::kColorAshFocusRing);
  51. // Install this highlight path generator to set the desired shape for
  52. // our focus ring.
  53. views::InstallRoundRectHighlightPathGenerator(this, gfx::Insets(),
  54. kTaskContinuationChipRadius);
  55. auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
  56. views::BoxLayout::Orientation::kVertical, kContinueBrowsingChipInsets,
  57. kContinueBrowsingChipSpacing));
  58. layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart);
  59. layout->set_cross_axis_alignment(
  60. views::BoxLayout::CrossAxisAlignment::kStart);
  61. // Inits the header view which consists of the favicon image and the url.
  62. auto* header_view = AddChildView(std::make_unique<views::View>());
  63. auto* header_layout =
  64. header_view->SetLayoutManager(std::make_unique<views::BoxLayout>(
  65. views::BoxLayout::Orientation::kHorizontal, gfx::Insets(),
  66. kContinueBrowsingChipFaviconSpacing));
  67. header_layout->set_main_axis_alignment(
  68. views::BoxLayout::MainAxisAlignment::kStart);
  69. header_layout->set_cross_axis_alignment(
  70. views::BoxLayout::CrossAxisAlignment::kCenter);
  71. auto* favicon =
  72. header_view->AddChildView(std::make_unique<views::ImageView>());
  73. favicon->SetImageSize(kContinueBrowsingChipFaviconSize);
  74. if (metadata.favicon.IsEmpty()) {
  75. favicon->SetImage(CreateVectorIcon(
  76. kPhoneHubDefaultFaviconIcon,
  77. AshColorProvider::Get()->GetContentLayerColor(
  78. AshColorProvider::ContentLayerType::kIconColorPrimary)));
  79. } else {
  80. favicon->SetImage(metadata.favicon.AsImageSkia());
  81. }
  82. auto* url_label = header_view->AddChildView(
  83. std::make_unique<views::Label>(base::UTF8ToUTF16(metadata.url.host())));
  84. url_label->SetAutoColorReadabilityEnabled(false);
  85. url_label->SetSubpixelRenderingEnabled(false);
  86. url_label->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor(
  87. AshColorProvider::ContentLayerType::kTextColorPrimary));
  88. url_label->SetElideBehavior(gfx::ElideBehavior::ELIDE_TAIL);
  89. auto* title_label =
  90. AddChildView(std::make_unique<views::Label>(metadata.title));
  91. title_label->SetAutoColorReadabilityEnabled(false);
  92. title_label->SetSubpixelRenderingEnabled(false);
  93. title_label->SetEnabledColor(color_provider->GetContentLayerColor(
  94. AshColorProvider::ContentLayerType::kTextColorPrimary));
  95. title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
  96. title_label->SetMultiLine(true);
  97. title_label->SetMaxLines(kTitleMaxLines);
  98. title_label->SetFontList(
  99. title_label->font_list().DeriveWithWeight(gfx::Font::Weight::BOLD));
  100. const std::u16string card_label = l10n_util::GetStringFUTF16(
  101. IDS_ASH_PHONE_HUB_CONTINUE_BROWSING_TAB_LABEL,
  102. base::NumberToString16(index_ + 1), base::NumberToString16(total_count_),
  103. metadata.title, base::UTF8ToUTF16(url_.spec()));
  104. SetTooltipText(card_label);
  105. SetAccessibleName(card_label);
  106. }
  107. void ContinueBrowsingChip::OnPaintBackground(gfx::Canvas* canvas) {
  108. cc::PaintFlags flags;
  109. flags.setAntiAlias(true);
  110. flags.setColor(AshColorProvider::Get()->GetControlsLayerColor(
  111. AshColorProvider::ControlsLayerType::kControlBackgroundColorInactive));
  112. gfx::Rect bounds = GetContentsBounds();
  113. canvas->DrawRoundRect(bounds, kTaskContinuationChipRadius, flags);
  114. views::View::OnPaintBackground(canvas);
  115. }
  116. ContinueBrowsingChip::~ContinueBrowsingChip() = default;
  117. const char* ContinueBrowsingChip::GetClassName() const {
  118. return "ContinueBrowsingChip";
  119. }
  120. void ContinueBrowsingChip::ButtonPressed() {
  121. PA_LOG(INFO) << "Opening browser tab: " << url_;
  122. phone_hub_metrics::LogTabContinuationChipClicked(index_);
  123. user_action_recorder_->RecordBrowserTabOpened();
  124. NewWindowDelegate::GetPrimary()->OpenUrl(
  125. url_, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
  126. NewWindowDelegate::Disposition::kNewForegroundTab);
  127. // Close Phone Hub bubble in current display.
  128. views::Widget* const widget = GetWidget();
  129. // |widget| is null when this function is called before the view is added to a
  130. // widget (in unit tests).
  131. if (!widget)
  132. return;
  133. int64_t current_display_id =
  134. display::Screen::GetScreen()
  135. ->GetDisplayNearestWindow(widget->GetNativeWindow())
  136. .id();
  137. Shell::GetRootWindowControllerWithDisplayId(current_display_id)
  138. ->GetStatusAreaWidget()
  139. ->phone_hub_tray()
  140. ->CloseBubble();
  141. }
  142. } // namespace ash