// Copyright 2023 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/overview/overview_drop_target.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/style/ash_color_id.h"
#include "ash/wm/desks/desks_util.h"
#include "ash/wm/overview/overview_grid.h"
#include "ash/wm/overview/overview_utils.h"
#include "ash/wm/window_util.h"
#include "ash/wm/wm_constants.h"
#include "base/memory/raw_ptr.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/rounded_corners_f.h"
#include "ui/views/background.h"
#include "ui/views/view.h"
#include "ui/views/view_utils.h"
#include "ui/views/widget/widget.h"
namespace ash {
constexpr int kDropTargetBorderThickness = 2;
// `OverviewDropTargetView` represents a transparent view with border in
// overview. It includes a background view. Dragged window in tablet mode can be
// dragged into it and then dropped into overview.
class OverviewDropTargetView : public views::View {
METADATA_HEADER(OverviewDropTargetView, views::View)
public:
OverviewDropTargetView() {
SetUseDefaultFillLayout(true);
background_view_ = AddChildView(std::make_unique<views::View>());
const int corner_radius = window_util::GetMiniWindowRoundedCornerRadius();
background_view_->SetBackground(views::CreateThemedRoundedRectBackground(
kColorAshShieldAndBase20, corner_radius));
SetBorder(views::CreateThemedRoundedRectBorder(
kDropTargetBorderThickness, corner_radius,
cros_tokens::kCrosSysSystemBaseElevated));
}
OverviewDropTargetView(const OverviewDropTargetView&) = delete;
OverviewDropTargetView& operator=(const OverviewDropTargetView&) = delete;
~OverviewDropTargetView() override = default;
// Updates the visibility of `background_view_` since it is only shown when
// drop target is selected in overview.
void UpdateBackgroundVisibility(bool visible) {
background_view_->SetVisible(visible);
}
raw_ptr<views::View> background_view_ = nullptr;
};
BEGIN_METADATA(OverviewDropTargetView)
END_METADATA
OverviewDropTarget::OverviewDropTarget(OverviewGrid* overview_grid)
: OverviewItemBase(overview_grid->overview_session(),
overview_grid,
overview_grid->root_window()) {
CreateItemWidget();
}
OverviewDropTarget::~OverviewDropTarget() = default;
void OverviewDropTarget::UpdateBackgroundVisibility(
const gfx::Point& location_in_screen) {
auto* drop_target_view = views::AsViewClass<OverviewDropTargetView>(
item_widget_->GetContentsView());
CHECK(drop_target_view);
drop_target_view->UpdateBackgroundVisibility(
item_widget_->GetWindowBoundsInScreen().Contains(location_in_screen));
}
void OverviewDropTarget::SetOpacity(float opacity) {}
aura::Window::Windows OverviewDropTarget::GetWindowsForHomeGesture() {
return {item_widget_->GetNativeWindow()};
}
void OverviewDropTarget::HideForSavedDeskLibrary(bool animate) {}
void OverviewDropTarget::RevertHideForSavedDeskLibrary(bool animate) {}
void OverviewDropTarget::UpdateMirrorsForDragging(bool is_touch_dragging) {}
void OverviewDropTarget::DestroyMirrorsForDragging() {}
aura::Window* OverviewDropTarget::GetWindow() {
return nullptr;
}
std::vector<raw_ptr<aura::Window, VectorExperimental>>
OverviewDropTarget::GetWindows() {
return {};
}
bool OverviewDropTarget::HasVisibleOnAllDesksWindow() {
return false;
}
bool OverviewDropTarget::Contains(const aura::Window* target) const {
return false;
}
OverviewItem* OverviewDropTarget::GetLeafItemForWindow(aura::Window* window) {
return nullptr;
}
void OverviewDropTarget::RestoreWindow(bool reset_transform, bool animate) {}
void OverviewDropTarget::SetBounds(const gfx::RectF& target_bounds,
OverviewAnimationType animation_type) {
target_bounds_ = target_bounds;
item_widget_->SetBounds(gfx::ToRoundedRect(target_bounds));
}
gfx::Transform OverviewDropTarget::ComputeTargetTransform(
const gfx::RectF& target_bounds) {
return gfx::Transform();
}
gfx::RectF OverviewDropTarget::GetWindowsUnionScreenBounds() const {
return target_bounds_;
}
gfx::RectF OverviewDropTarget::GetTargetBoundsWithInsets() const {
return GetWindowsUnionScreenBounds();
}
gfx::RectF OverviewDropTarget::GetTransformedBounds() const {
return GetWindowsUnionScreenBounds();
}
float OverviewDropTarget::GetItemScale(int height) {
return 1.f;
}
void OverviewDropTarget::ScaleUpSelectedItem(
OverviewAnimationType animation_type) {}
void OverviewDropTarget::EnsureVisible() {}
std::vector<views::Widget*> OverviewDropTarget::GetFocusableWidgets() {
return {};
}
views::View* OverviewDropTarget::GetBackDropView() const {
return nullptr;
}
bool OverviewDropTarget::ShouldHaveShadow() const {
return false;
}
void OverviewDropTarget::UpdateRoundedCornersAndShadow() {}
float OverviewDropTarget::GetOpacity() const {
return 1.f;
}
void OverviewDropTarget::PrepareForOverview() {}
void OverviewDropTarget::SetShouldUseSpawnAnimation(bool value) {}
void OverviewDropTarget::OnStartingAnimationComplete() {}
void OverviewDropTarget::Restack() {}
void OverviewDropTarget::StartDrag() {}
void OverviewDropTarget::OnOverviewItemDragStarted() {}
void OverviewDropTarget::OnOverviewItemDragEnded(bool snap) {}
void OverviewDropTarget::OnOverviewItemContinuousScroll(
const gfx::Transform& target_transform,
float scroll_ratio) {}
void OverviewDropTarget::UpdateCannotSnapWarningVisibility(bool animate) {}
void OverviewDropTarget::HideCannotSnapWarning(bool animate) {}
void OverviewDropTarget::OnMovingItemToAnotherDesk() {}
void OverviewDropTarget::Shutdown() {}
void OverviewDropTarget::AnimateAndCloseItem(bool up) {}
void OverviewDropTarget::StopWidgetAnimation() {}
OverviewItemFillMode OverviewDropTarget::GetOverviewItemFillMode() const {
return OverviewItemFillMode::kNormal;
}
void OverviewDropTarget::UpdateOverviewItemFillMode() {}
const gfx::RoundedCornersF OverviewDropTarget::GetRoundedCorners() const {
return gfx::RoundedCornersF();
}
void OverviewDropTarget::CreateItemWidget() {
item_widget_ = std::make_unique<views::Widget>(CreateOverviewItemWidgetParams(
desks_util::GetActiveDeskContainerForRoot(root_window_),
"OverviewOverviewDropTarget", /*accept_events=*/false));
item_widget_->set_focus_on_creation(false);
item_widget_->SetVisibilityAnimationTransition(views::Widget::ANIMATE_NONE);
item_widget_->SetContentsView(std::make_unique<OverviewDropTargetView>());
aura::Window* drop_target_window = item_widget_->GetNativeWindow();
drop_target_window->parent()->StackChildAtBottom(drop_target_window);
item_widget_->Show();
}
} // namespace ash