window_cycle_item_view.cc 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. // Copyright 2021 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/wm/window_cycle/window_cycle_item_view.h"
  5. #include "ash/shell.h"
  6. #include "ash/wm/window_cycle/window_cycle_controller.h"
  7. #include "ash/wm/window_preview_view.h"
  8. #include "ui/aura/window.h"
  9. #include "ui/base/metadata/metadata_impl_macros.h"
  10. #include "ui/gfx/geometry/rect_f.h"
  11. #include "ui/views/accessibility/accessibility_paint_checks.h"
  12. #include "ui/views/view.h"
  13. namespace ash {
  14. namespace {
  15. // The min and max width for preview size are in relation to the fixed height.
  16. constexpr int kMinPreviewWidthDp =
  17. WindowCycleItemView::kFixedPreviewHeightDp / 2;
  18. constexpr int kMaxPreviewWidthDp =
  19. WindowCycleItemView::kFixedPreviewHeightDp * 2;
  20. } // namespace
  21. WindowCycleItemView::WindowCycleItemView(aura::Window* window)
  22. : WindowMiniView(window) {
  23. SetFocusBehavior(FocusBehavior::ALWAYS);
  24. SetNotifyEnterExitOnChild(true);
  25. // TODO(crbug.com/1218186): Remove this, this is in place temporarily to be
  26. // able to submit accessibility checks, but this focusable View needs to
  27. // add a name so that the screen reader knows what to announce.
  28. SetProperty(views::kSkipAccessibilityPaintChecks, true);
  29. }
  30. void WindowCycleItemView::ShowPreview() {
  31. DCHECK(!preview_view());
  32. UpdateIconView();
  33. SetShowPreview(/*show=*/true);
  34. UpdatePreviewRoundedCorners(/*show=*/true);
  35. }
  36. void WindowCycleItemView::OnMouseEntered(const ui::MouseEvent& event) {
  37. Shell::Get()->window_cycle_controller()->SetFocusedWindow(source_window());
  38. }
  39. bool WindowCycleItemView::OnMousePressed(const ui::MouseEvent& event) {
  40. Shell::Get()->window_cycle_controller()->SetFocusedWindow(source_window());
  41. Shell::Get()->window_cycle_controller()->CompleteCycling();
  42. return true;
  43. }
  44. gfx::Size WindowCycleItemView::GetPreviewViewSize() const {
  45. // When the preview is not shown, do an estimate of the expected size.
  46. // |this| will not be visible anyways, and will get corrected once
  47. // ShowPreview() is called.
  48. if (!preview_view()) {
  49. gfx::SizeF source_size(source_window()->bounds().size());
  50. // Windows may have no size in tests.
  51. if (source_size.IsEmpty())
  52. return gfx::Size();
  53. const float aspect_ratio = source_size.width() / source_size.height();
  54. return gfx::Size(kFixedPreviewHeightDp * aspect_ratio,
  55. kFixedPreviewHeightDp);
  56. }
  57. // Returns the size for the preview view, scaled to fit within the max
  58. // bounds. Scaling is always 1:1 and we only scale down, never up.
  59. gfx::Size preview_pref_size = preview_view()->GetPreferredSize();
  60. if (preview_pref_size.width() > kMaxPreviewWidthDp ||
  61. preview_pref_size.height() > kFixedPreviewHeightDp) {
  62. const float scale = std::min(
  63. kMaxPreviewWidthDp / static_cast<float>(preview_pref_size.width()),
  64. kFixedPreviewHeightDp / static_cast<float>(preview_pref_size.height()));
  65. preview_pref_size =
  66. gfx::ScaleToFlooredSize(preview_pref_size, scale, scale);
  67. }
  68. return preview_pref_size;
  69. }
  70. void WindowCycleItemView::Layout() {
  71. WindowMiniView::Layout();
  72. if (!preview_view())
  73. return;
  74. // Show the backdrop if the preview view does not take up all the bounds
  75. // allocated for it.
  76. gfx::Rect preview_max_bounds = GetContentsBounds();
  77. preview_max_bounds.Subtract(GetHeaderBounds());
  78. const gfx::Rect preview_area_bounds = preview_view()->bounds();
  79. SetBackdropVisibility(preview_max_bounds.size() !=
  80. preview_area_bounds.size());
  81. }
  82. gfx::Size WindowCycleItemView::CalculatePreferredSize() const {
  83. // Previews can range in width from half to double of
  84. // |kFixedPreviewHeightDp|. Padding will be added to the
  85. // sides to achieve this if the preview is too narrow.
  86. gfx::Size preview_size = GetPreviewViewSize();
  87. // All previews are the same height (this may add padding on top and
  88. // bottom).
  89. preview_size.set_height(kFixedPreviewHeightDp);
  90. // Previews should never be narrower than half or wider than double their
  91. // fixed height.
  92. preview_size.set_width(base::clamp(preview_size.width(), kMinPreviewWidthDp,
  93. kMaxPreviewWidthDp));
  94. const int margin = GetInsets().width();
  95. preview_size.Enlarge(margin, margin + WindowMiniView::kHeaderHeightDp);
  96. return preview_size;
  97. }
  98. BEGIN_METADATA(WindowCycleItemView, WindowMiniView)
  99. END_METADATA
  100. } // namespace ash