// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_STYLE_SYSTEM_SHADOW_ON_NINE_PATCH_LAYER_H_
#define ASH_STYLE_SYSTEM_SHADOW_ON_NINE_PATCH_LAYER_H_
#include "ash/style/system_shadow.h"
#include "base/scoped_observation.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/compositor_extra/shadow.h"
#include "ui/views/view_observer.h"
#include "ui/views/view_shadow.h"
namespace ui {
class ColorProvider;
class Layer;
} // namespace ui
namespace ash {
// SystemShadowOnNinePatchLayer is an interface for the shadows based on
// ui::Shadow which paints shadow on a nine patch layer. The shadow attributes
// are set and get from ui::Shadow's functions. The child classes need to expose
// their ui::Shadow pointer in `shadow()`.
class SystemShadowOnNinePatchLayer : public SystemShadow {
public:
~SystemShadowOnNinePatchLayer() override;
// SystemShadow:
void SetType(SystemShadow::Type type) override;
void SetContentBounds(const gfx::Rect& bounds) override;
void SetRoundedCornerRadius(int corner_radius) override;
void SetRoundedCorners(const gfx::RoundedCornersF& rounded_corners) override;
const gfx::Rect& GetContentBounds() override;
ui::Layer* GetLayer() override;
ui::Layer* GetNinePatchLayer() override;
const gfx::ShadowValues GetShadowValuesForTesting() const override;
protected:
virtual ui::Shadow* shadow() = 0;
virtual const ui::Shadow* shadow() const = 0;
private:
// SystemShadow:
void UpdateShadowColors(const ui::ColorProvider* color_provider) override;
};
// An implementation of `SystemShadowOnNinePatchLayer`. It is directly based on
// the ui::Shadow.
class SystemShadowOnNinePatchLayerImpl : public SystemShadowOnNinePatchLayer,
public ui::LayerOwner::Observer {
public:
SystemShadowOnNinePatchLayerImpl(
SystemShadow::Type type,
const LayerRecreatedCallback& layer_recreated_callback);
SystemShadowOnNinePatchLayerImpl(const SystemShadowOnNinePatchLayerImpl&) =
delete;
SystemShadowOnNinePatchLayerImpl& operator=(
const SystemShadowOnNinePatchLayerImpl&) = delete;
~SystemShadowOnNinePatchLayerImpl() override;
// ui::LayerOwner::Observer:
void OnLayerRecreated(ui::Layer* old_layer) override;
private:
// SystemShadowOnNinePatchLayer:
ui::Shadow* shadow() override;
const ui::Shadow* shadow() const override;
LayerRecreatedCallback layer_recreated_callback_;
ui::Shadow shadow_;
base::ScopedObservation<ui::LayerOwner, SystemShadowOnNinePatchLayerImpl>
shadow_observation_{this};
};
// An implementation of `SystemShadowOnNinePatchLayer`. It is based on
// ViewShadow. The ViewShadow is added in the layers beneath the view and
// adjusts its content bounds with the view's bounds. Do not manually set the
// content bounds.
class SystemViewShadowOnNinePatchLayer : public SystemShadowOnNinePatchLayer,
public views::ViewObserver {
public:
SystemViewShadowOnNinePatchLayer(views::View* view, SystemShadow::Type type);
SystemViewShadowOnNinePatchLayer(const SystemViewShadowOnNinePatchLayer&) =
delete;
SystemViewShadowOnNinePatchLayer& operator=(
const SystemViewShadowOnNinePatchLayer&) = delete;
~SystemViewShadowOnNinePatchLayer() override;
// SystemShadow:
void SetRoundedCornerRadius(int corner_radius) override;
// views::ViewObserver:
void OnViewAddedToWidget(views::View* observed_view) override;
void OnViewIsDeleting(views::View* observed_view) override;
private:
// SystemShadowOnNinePatchLayer:
void SetContentBounds(const gfx::Rect& content_bounds) override;
ui::Shadow* shadow() override;
const ui::Shadow* shadow() const override;
views::ViewShadow view_shadow_;
base::ScopedObservation<views::View, views::ViewObserver> view_observation_{
this};
};
// An extension of SystemShadowOnNinePatchLayerImpl. The shadow is added at the
// bottom of a window's layer and adjusts its content bounds with the window's
// bounds. Do not manually set the content bounds.
class SystemWindowShadowOnNinePatchLayer
: public SystemShadowOnNinePatchLayerImpl,
public aura::WindowObserver {
public:
SystemWindowShadowOnNinePatchLayer(aura::Window* window,
SystemShadow::Type type);
SystemWindowShadowOnNinePatchLayer(
const SystemWindowShadowOnNinePatchLayer&) = delete;
SystemWindowShadowOnNinePatchLayer& operator=(
const SystemWindowShadowOnNinePatchLayer&) = delete;
~SystemWindowShadowOnNinePatchLayer() override;
// aura::WindowObserver:
void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
ui::PropertyChangeReason reason) override;
void OnWindowDestroyed(aura::Window* window) override;
void OnWindowAddedToRootWindow(aura::Window* window) override;
private:
// SystemShadowOnNinePatchLayerImpl:
void SetContentBounds(const gfx::Rect& content_bounds) override;
base::ScopedObservation<aura::Window, aura::WindowObserver>
window_observation_{this};
};
} // namespace ash
#endif // ASH_STYLE_SYSTEM_SHADOW_ON_NINE_PATCH_LAYER_H_