1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125

ash / wm / window_restore / informed_restore_screenshot_icon_row_view.cc [blame]

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/wm/window_restore/informed_restore_screenshot_icon_row_view.h"

#include "ash/public/cpp/saved_desk_delegate.h"
#include "ash/shell.h"
#include "ash/style/ash_color_id.h"
#include "ash/style/typography.h"
#include "ash/wm/window_restore/informed_restore_app_image_view.h"
#include "ash/wm/window_restore/informed_restore_constants.h"
#include "ash/wm/window_restore/informed_restore_item_view.h"
#include "ash/wm/window_restore/window_restore_util.h"
#include "base/i18n/number_formatting.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
#include "ui/views/background.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/separator.h"

namespace ash {

namespace {

constexpr gfx::Insets kIconRowInsets =
    gfx::Insets::TLBR(informed_restore::kPreviewContainerRadius + 4, 4, 4, 4);
constexpr int kIconRowHeight = informed_restore::kScreenshotIconRowIconSize +
                               kIconRowInsets.top() + kIconRowInsets.bottom();

// Returns the preferred size of the icon row. `child_number` indicates the
// number of children while `one_browser_window` indicates it is only one
// browser window opened, which means the favicons of the tabs will be shown
// instead.
gfx::Size GetPreferredSizeOfTheRow(int child_number, bool one_browser_window) {
  int width = child_number * informed_restore::kScreenshotIconRowIconSize +
              kIconRowInsets.left() + kIconRowInsets.right() +
              informed_restore::kPreviewContainerRadius;
  if (one_browser_window) {
    width += 2 * informed_restore::kScreenshotIconRowChildSpacing +
             (child_number - 2) * informed_restore::kScreenshotFaviconSpacing +
             views::Separator::kThickness;
  } else {
    width +=
        (child_number - 1) * informed_restore::kScreenshotIconRowChildSpacing;
  }
  return gfx::Size(width, kIconRowHeight);
}

}  // namespace

InformedRestoreScreenshotIconRowView::InformedRestoreScreenshotIconRowView(
    const InformedRestoreContentsData::AppsInfos& apps_infos) {
  SetID(informed_restore::kScreenshotIconRowViewID);
  SetCrossAxisAlignment(views::BoxLayout::CrossAxisAlignment::kStart);
  SetOrientation(views::BoxLayout::Orientation::kHorizontal);
  SetBetweenChildSpacing(informed_restore::kScreenshotIconRowChildSpacing);
  SetInsideBorderInsets(kIconRowInsets);
  SetBackground(
      views::CreateThemedSolidBackground(kColorAshShieldAndBaseOpaque));
  // Do not flip this view in RTL, since the cutout in
  // `InformedRestoreContentsView` is not flipped.
  SetMirrored(false);

  const int elements_size = static_cast<int>(apps_infos.size());
  const bool one_browser_window =
      elements_size == 1 && IsBrowserAppId(apps_infos[0].app_id);

  // If there is only one browser window, show the browser icon and its tabs
  // favicons inside the icon row view.
  if (one_browser_window) {
    AddChildView(std::make_unique<InformedRestoreItemView>(apps_infos[0],
                                                /*inside_screenshot=*/true));
  } else {
    const bool exceed_max_elements =
        elements_size > informed_restore::kScreenshotIconRowMaxElements;
    // If there are more than `kScreenshotIconRowMaxElements` number of windows,
    // show `kScreenshotIconRowMaxElements - 1` number of icons and save the
    // last spot in the row to count the remaining windows.
    const int num_icon =
        exceed_max_elements
            ? informed_restore::kScreenshotIconRowMaxElements - 1
            : elements_size;

    for (int i = 0; i < num_icon; i++) {
      auto image_view = std::make_unique<InformedRestoreAppImageView>(
          apps_infos[i].app_id, InformedRestoreAppImageView::Type::kScreenshot,
          base::DoNothing());
      image_view->SetID(informed_restore::kScreenshotImageViewID);
      AddChildView(std::move(image_view));
    }
    if (exceed_max_elements) {
      auto* count_label = AddChildView(
          views::Builder<views::Label>()
              .SetText(u"+" + base::FormatNumber(elements_size - num_icon))
              .SetPreferredSize(
                  informed_restore::kScreenshotIconRowImageViewSize)
              .SetEnabledColorId(cros_tokens::kCrosSysOnPrimaryContainer)
              .SetBackground(views::CreateThemedRoundedRectBackground(
                  cros_tokens::kCrosSysPrimaryContainer,
                  informed_restore::kScreenshotIconRowIconSize / 2.0))
              .Build());
      TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosLabel2,
                                            *count_label);
    }
  }
  int child_number = std::min(
      informed_restore::kScreenshotIconRowMaxElements,
      one_browser_window ? static_cast<int>(apps_infos[0].tab_infos.size())
                         : elements_size);
  // Add the browser icon when there is only one browser window opened.
  if (one_browser_window) {
    child_number++;
  }
  SetPreferredSize(GetPreferredSizeOfTheRow(child_number, one_browser_window));
}

InformedRestoreScreenshotIconRowView::~InformedRestoreScreenshotIconRowView()
    = default;

BEGIN_METADATA(InformedRestoreScreenshotIconRowView)
END_METADATA

}  // namespace ash