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

ash / wm / splitview / split_view_setup_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/splitview/split_view_setup_view.h"

#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/style/ash_color_id.h"
#include "ash/style/icon_button.h"
#include "ash/style/style_util.h"
#include "ash/style/system_shadow.h"
#include "ash/system/toast/system_toast_view.h"
#include "ash/wm/wm_constants.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/compositor/layer.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/highlight_border.h"

namespace ash {

namespace {

// Distance from the right of the faster splitscreen toast to the left of the
// settings button.
constexpr int kSettingsButtonSpacingDp = 8;

// -----------------------------------------------------------------------------
// SplitViewSetupViewSettingsButton:

// Settings button in the faster split screen setup that can deep link to the
// window snap preference section upon clicking.
class SplitViewSetupViewSettingsButton : public IconButton {
  METADATA_HEADER(SplitViewSetupViewSettingsButton, IconButton)

 public:
  explicit SplitViewSetupViewSettingsButton(
      base::RepeatingClosure settings_callback)
      : IconButton(std::move(settings_callback),
                   IconButton::Type::kLarge,
                   &kOverviewSettingsIcon,
                   IDS_ASH_OVERVIEW_SETTINGS_BUTTON_LABEL),
        shadow_(SystemShadow::CreateShadowOnTextureLayer(
            SystemShadow::Type::kElevation4)) {
    SetPaintToLayer();
    layer()->SetFillsBoundsOpaquely(false);
    SetBackgroundColor(kColorAshShieldAndBase80);

    const float settings_button_corner_radius =
        GetPreferredSize().height() / 2.0f;
    SetBorder(std::make_unique<views::HighlightBorder>(
        settings_button_corner_radius,
        views::HighlightBorder::Type::kHighlightBorderOnShadow));
    shadow_->SetRoundedCornerRadius(settings_button_corner_radius);

    StyleUtil::SetUpFocusRingForView(this, kWindowMiniViewFocusRingHaloInset);
  }

  SplitViewSetupViewSettingsButton(const SplitViewSetupViewSettingsButton&) = delete;
  SplitViewSetupViewSettingsButton& operator=(
      const SplitViewSetupViewSettingsButton&) = delete;
  ~SplitViewSetupViewSettingsButton() override = default;

  // views::View:
  void AddedToWidget() override {
    // Since the layer of the shadow has to be added as a sibling to this view's
    // layer, we need to wait until the view is added to the widget.
    auto* parent = layer()->parent();
    parent->Add(shadow_->GetLayer());
    parent->StackAtBottom(shadow_->GetLayer());
  }

  void OnBoundsChanged(const gfx::Rect& previous_bounds) override {
    // The shadow layer is a sibling of this view's layer, whose contents bounds
    // should be the same as the view's bounds.
    shadow_->SetContentBounds(layer()->bounds());
  }

 private:
  std::unique_ptr<SystemShadow> shadow_;
};

BEGIN_METADATA(SplitViewSetupViewSettingsButton)
END_METADATA

}  // namespace

// -----------------------------------------------------------------------------
// SplitViewSetupView:

SplitViewSetupView::SplitViewSetupView(base::RepeatingClosure skip_callback,
                                 base::RepeatingClosure settings_callback) {
  SetOrientation(views::BoxLayout::Orientation::kHorizontal);
  SetBetweenChildSpacing(kSettingsButtonSpacingDp);

  auto* toast = AddChildView(std::make_unique<SystemToastView>(
      /*text=*/l10n_util::GetStringUTF16(
          IDS_ASH_OVERVIEW_FASTER_SPLITSCREEN_TOAST),
      SystemToastView::ButtonType::kTextButton,
      /*button_text=*/
      l10n_util::GetStringUTF16(IDS_ASH_OVERVIEW_FASTER_SPLITSCREEN_TOAST_SKIP),
      /*button_icon=*/&gfx::kNoneIcon,
      /*button_callback=*/std::move(skip_callback),
      /*leading_icon=*/&gfx::kNoneIcon));
  auto* dismiss_button = toast->button();
  dismiss_button->SetTooltipText(l10n_util::GetStringUTF16(
      IDS_ASH_OVERVIEW_FASTER_SPLITSCREEN_TOAST_DISMISS_WINDOW_SUGGESTIONS));
  dismiss_button->SetID(kDismissButtonIDForTest);

  auto* settings_button =
      AddChildView(std::make_unique<SplitViewSetupViewSettingsButton>(
          std::move(settings_callback)));
  settings_button->SetID(kSettingsButtonIDForTest);
}

SplitViewSetupView::~SplitViewSetupView() = default;

BEGIN_METADATA(SplitViewSetupView)
END_METADATA

}  // namespace ash