Commit 957114a2 authored by Sammie Quon's avatar Sammie Quon Committed by Commit Bot

overview: Add shadows to close button, title and window icon.

This requires some changes to WindowMiniView to make it more
customizeable as UX specifically only wants shadows on overview and not
alt-tab. Changes made were to apply effects on an icon supplied through
a window property, in this case a shadow.

Also, adding shadow to a label will shift the text. Since we want to
keep the text right aligned with the icon, make OverviewItemView
header layout code custom (previously was using the default from
WindowMiniView FlexLayout).

Test: manual
Fixed: 1028845
Change-Id: Ief8e9bbccc42fa198ff31729b735edc519d78270
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2128835Reviewed-by: default avatarAhmed Fakhry <afakhry@chromium.org>
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#755964}
parent 8d688b75
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "ui/compositor/layer.h" #include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/paint_vector_icon.h" #include "ui/gfx/paint_vector_icon.h"
#include "ui/strings/grit/ui_strings.h" #include "ui/strings/grit/ui_strings.h"
#include "ui/views/animation/flood_fill_ink_drop_ripple.h" #include "ui/views/animation/flood_fill_ink_drop_ripple.h"
...@@ -29,6 +30,7 @@ ...@@ -29,6 +30,7 @@
#include "ui/views/animation/ink_drop_mask.h" #include "ui/views/animation/ink_drop_mask.h"
#include "ui/views/controls/button/image_button.h" #include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/highlight_path_generator.h" #include "ui/views/controls/highlight_path_generator.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h" #include "ui/views/controls/label.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
...@@ -66,6 +68,21 @@ constexpr SkColor kCloseButtonInkDropRippleColor = ...@@ -66,6 +68,21 @@ constexpr SkColor kCloseButtonInkDropRippleColor =
constexpr SkColor kCloseButtonInkDropRippleHighlightColor = constexpr SkColor kCloseButtonInkDropRippleHighlightColor =
SkColorSetA(kCloseButtonColor, 0x14); SkColorSetA(kCloseButtonColor, 0x14);
// Shadow values for shadow on overview header views.
constexpr int kTitleShadowBlur = 28;
constexpr SkColor kTitleShadowColor = SkColorSetA(SK_ColorBLACK, 82);
constexpr int kIconShadowBlur = 10;
constexpr SkColor kIconShadowColor = SkColorSetA(SK_ColorBLACK, 31);
gfx::ShadowValues GetTitleShadowValues() {
return {
gfx::ShadowValue(gfx::Vector2d(), kTitleShadowBlur, kTitleShadowColor)};
}
gfx::ShadowValues GetIconShadowValues() {
return {gfx::ShadowValue(gfx::Vector2d(), kIconShadowBlur, kIconShadowColor)};
}
// Animates |layer| from 0 -> 1 opacity if |visible| and 1 -> 0 opacity // Animates |layer| from 0 -> 1 opacity if |visible| and 1 -> 0 opacity
// otherwise. The tween type differs for |visible| and if |visible| is true // otherwise. The tween type differs for |visible| and if |visible| is true
// there is a slight delay before the animation begins. Does not animate if // there is a slight delay before the animation begins. Does not animate if
...@@ -95,9 +112,14 @@ class OverviewCloseButton : public views::ImageButton { ...@@ -95,9 +112,14 @@ class OverviewCloseButton : public views::ImageButton {
explicit OverviewCloseButton(views::ButtonListener* listener) explicit OverviewCloseButton(views::ButtonListener* listener)
: views::ImageButton(listener) { : views::ImageButton(listener) {
SetInkDropMode(InkDropMode::ON_NO_GESTURE_HANDLER); SetInkDropMode(InkDropMode::ON_NO_GESTURE_HANDLER);
SetImage(
views::Button::STATE_NORMAL, // Add a shadow to the close vector icon.
gfx::CreateVectorIcon(kOverviewWindowCloseIcon, kCloseButtonColor)); gfx::ImageSkia image_shadow =
gfx::ImageSkiaOperations::CreateImageWithDropShadow(
gfx::CreateVectorIcon(kOverviewWindowCloseIcon, kCloseButtonColor),
GetIconShadowValues());
SetImage(views::Button::STATE_NORMAL, image_shadow);
SetImageHorizontalAlignment(views::ImageButton::ALIGN_CENTER); SetImageHorizontalAlignment(views::ImageButton::ALIGN_CENTER);
SetImageVerticalAlignment(views::ImageButton::ALIGN_MIDDLE); SetImageVerticalAlignment(views::ImageButton::ALIGN_MIDDLE);
SetMinimumImageSize(gfx::Size(kHeaderHeightDp, kHeaderHeightDp)); SetMinimumImageSize(gfx::Size(kHeaderHeightDp, kHeaderHeightDp));
...@@ -107,11 +129,9 @@ class OverviewCloseButton : public views::ImageButton { ...@@ -107,11 +129,9 @@ class OverviewCloseButton : public views::ImageButton {
views::InstallFixedSizeCircleHighlightPathGenerator( views::InstallFixedSizeCircleHighlightPathGenerator(
this, kCloseButtonInkDropRadiusDp); this, kCloseButtonInkDropRadiusDp);
} }
~OverviewCloseButton() override = default;
OverviewCloseButton(const OverviewCloseButton&) = delete; OverviewCloseButton(const OverviewCloseButton&) = delete;
OverviewCloseButton& operator=(const OverviewCloseButton&) = delete; OverviewCloseButton& operator=(const OverviewCloseButton&) = delete;
~OverviewCloseButton() override = default;
// Resets the listener so that the listener can go out of scope. // Resets the listener so that the listener can go out of scope.
void ResetListener() { listener_ = nullptr; } void ResetListener() { listener_ = nullptr; }
...@@ -155,6 +175,11 @@ OverviewItemView::OverviewItemView(OverviewItem* overview_item, ...@@ -155,6 +175,11 @@ OverviewItemView::OverviewItemView(OverviewItem* overview_item,
std::make_unique<OverviewCloseButton>(overview_item_)); std::make_unique<OverviewCloseButton>(overview_item_));
close_button_->SetPaintToLayer(); close_button_->SetPaintToLayer();
close_button_->layer()->SetFillsBoundsOpaquely(false); close_button_->layer()->SetFillsBoundsOpaquely(false);
// The button's image may be larger than |kHeaderHeightDp| due to added
// shadows.
close_button_->SetPreferredSize(gfx::Size(kHeaderHeightDp, kHeaderHeightDp));
title_label()->SetShadows(GetTitleShadowValues());
// Call this last as it calls |Layout()| which relies on the some of the other // Call this last as it calls |Layout()| which relies on the some of the other
// elements existing. // elements existing.
...@@ -167,6 +192,13 @@ OverviewItemView::OverviewItemView(OverviewItem* overview_item, ...@@ -167,6 +192,13 @@ OverviewItemView::OverviewItemView(OverviewItem* overview_item,
} }
border_ptr()->set_extra_margin(kWindowMargin); border_ptr()->set_extra_margin(kWindowMargin);
UpdateIconView();
// Do not use a layout manager for the header as its elements have shadows
// which need to overlap each other. Remove the FlexLayout set in
// WindowMiniView.
header_view()->SetLayoutManager(nullptr);
} }
OverviewItemView::~OverviewItemView() = default; OverviewItemView::~OverviewItemView() = default;
...@@ -239,8 +271,7 @@ gfx::Rect OverviewItemView::GetHeaderBounds() const { ...@@ -239,8 +271,7 @@ gfx::Rect OverviewItemView::GetHeaderBounds() const {
// additional padding would be equal to half the difference in width between // additional padding would be equal to half the difference in width between
// the preferred width and the image size. The resulting padding would be that // the preferred width and the image size. The resulting padding would be that
// number plus the padding in the resource, in dips. // number plus the padding in the resource, in dips.
const int image_width = const int image_width = kIconSize.width();
close_button_->GetImage(views::ImageButton::STATE_NORMAL).width();
const int close_button_width = close_button_->GetPreferredSize().width(); const int close_button_width = close_button_->GetPreferredSize().width();
const int right_padding = const int right_padding =
(close_button_width - image_width) / 2 + kCloseButtonIconMarginDp; (close_button_width - image_width) / 2 + kCloseButtonIconMarginDp;
...@@ -291,6 +322,41 @@ gfx::Size OverviewItemView::GetPreviewViewSize() const { ...@@ -291,6 +322,41 @@ gfx::Size OverviewItemView::GetPreviewViewSize() const {
return gfx::ToRoundedSize(target_size); return gfx::ToRoundedSize(target_size);
} }
gfx::ImageSkia OverviewItemView::ModifyIcon(gfx::ImageSkia* image) const {
gfx::ImageSkia image_resized = gfx::ImageSkiaOperations::CreateResizedImage(
*image, skia::ImageOperations::RESIZE_BEST, kIconSize);
return gfx::ImageSkiaOperations::CreateImageWithDropShadow(
image_resized, GetIconShadowValues());
}
void OverviewItemView::Layout() {
WindowMiniView::Layout();
// Layout the header items. The icon, if available should be aligned left, the
// close button should be aligned right and the title should take up all the
// space in between but the text should be aligned left.
gfx::Rect header_bounds = header_view()->GetLocalBounds();
const int width = header_bounds.width();
const int height = header_bounds.height();
int x = 0;
if (icon_view()) {
const int icon_width = kIconSize.width();
icon_view()->SetBounds(x, 0, icon_width, height);
x += icon_width;
}
const gfx::Size close_button_size = close_button()->GetPreferredSize();
close_button()->SetBoundsRect(gfx::Rect(
gfx::Point(width - close_button_size.width(), 0), close_button_size));
// The title label text has shadow blur of |kTitleShadowBlur|. This will cause
// the preferred size of the title label to increase by |kTitleShadowBlur| / 2
// on all sides. To create the visual of the title label being
// |kHeaderPaddingDp| away from the icon (excluding the shadows), layout it
// somewhat on top of the icon.
x -= (kTitleShadowBlur / 2 - kHeaderPaddingDp);
title_label()->SetBounds(x, 0, width - close_button_size.width() - x, height);
}
views::View* OverviewItemView::GetView() { views::View* OverviewItemView::GetView() {
return this; return this;
} }
......
...@@ -65,6 +65,8 @@ class ASH_EXPORT OverviewItemView ...@@ -65,6 +65,8 @@ class ASH_EXPORT OverviewItemView
int GetMargin() const override; int GetMargin() const override;
gfx::Rect GetHeaderBounds() const override; gfx::Rect GetHeaderBounds() const override;
gfx::Size GetPreviewViewSize() const override; gfx::Size GetPreviewViewSize() const override;
gfx::ImageSkia ModifyIcon(gfx::ImageSkia* image) const override;
void Layout() override;
// OverviewHighlightController::OverviewHighlightableView: // OverviewHighlightController::OverviewHighlightableView:
views::View* GetView() override; views::View* GetView() override;
......
...@@ -159,6 +159,7 @@ class WindowCycleItemView : public WindowMiniView { ...@@ -159,6 +159,7 @@ class WindowCycleItemView : public WindowMiniView {
SetShowPreview(/*show=*/true); SetShowPreview(/*show=*/true);
UpdatePreviewRoundedCorners(/*show=*/true); UpdatePreviewRoundedCorners(/*show=*/true);
SetFocusBehavior(FocusBehavior::ALWAYS); SetFocusBehavior(FocusBehavior::ALWAYS);
UpdateIconView();
} }
~WindowCycleItemView() override = default; ~WindowCycleItemView() override = default;
......
...@@ -28,13 +28,6 @@ namespace { ...@@ -28,13 +28,6 @@ namespace {
// Foreground label color. // Foreground label color.
constexpr SkColor kLabelColor = SK_ColorWHITE; constexpr SkColor kLabelColor = SK_ColorWHITE;
// Horizontal padding for the label, on both sides.
constexpr int kHorizontalLabelPaddingDp = 12;
// The size in dp of the window icon shown on the overview window next to the
// title.
constexpr gfx::Size kIconSize{24, 24};
// The font delta of the window title. // The font delta of the window title.
constexpr int kLabelFontDelta = 2; constexpr int kLabelFontDelta = 2;
...@@ -46,6 +39,9 @@ constexpr SkColor kBackdropColor = SkColorSetA(SK_ColorWHITE, 0x24); ...@@ -46,6 +39,9 @@ constexpr SkColor kBackdropColor = SkColorSetA(SK_ColorWHITE, 0x24);
WindowMiniView::~WindowMiniView() = default; WindowMiniView::~WindowMiniView() = default;
constexpr gfx::Size WindowMiniView::kIconSize;
constexpr int WindowMiniView::kHeaderPaddingDp;
void WindowMiniView::SetBackdropVisibility(bool visible) { void WindowMiniView::SetBackdropVisibility(bool visible) {
if (!backdrop_view_ && !visible) if (!backdrop_view_ && !visible)
return; return;
...@@ -121,6 +117,11 @@ gfx::Size WindowMiniView::GetPreviewViewSize() const { ...@@ -121,6 +117,11 @@ gfx::Size WindowMiniView::GetPreviewViewSize() const {
return preview_view_->GetPreferredSize(); return preview_view_->GetPreferredSize();
} }
gfx::ImageSkia WindowMiniView::ModifyIcon(gfx::ImageSkia* image) const {
return gfx::ImageSkiaOperations::CreateResizedImage(
*image, skia::ImageOperations::RESIZE_BEST, kIconSize);
}
WindowMiniView::WindowMiniView(aura::Window* source_window) WindowMiniView::WindowMiniView(aura::Window* source_window)
: source_window_(source_window) { : source_window_(source_window) {
SetPaintToLayer(); SetPaintToLayer();
...@@ -134,9 +135,7 @@ WindowMiniView::WindowMiniView(aura::Window* source_window) ...@@ -134,9 +135,7 @@ WindowMiniView::WindowMiniView(aura::Window* source_window)
views::BoxLayout* layout = views::BoxLayout* layout =
header_view_->SetLayoutManager(std::make_unique<views::BoxLayout>( header_view_->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), views::BoxLayout::Orientation::kHorizontal, gfx::Insets(),
kHorizontalLabelPaddingDp)); kHeaderPaddingDp));
UpdateIconView();
title_label_ = header_view_->AddChildView(std::make_unique<views::Label>( title_label_ = header_view_->AddChildView(std::make_unique<views::Label>(
wm::GetTransientRoot(source_window_)->GetTitle())); wm::GetTransientRoot(source_window_)->GetTitle()));
...@@ -154,6 +153,24 @@ WindowMiniView::WindowMiniView(aura::Window* source_window) ...@@ -154,6 +153,24 @@ WindowMiniView::WindowMiniView(aura::Window* source_window)
SetBorder(std::move(border)); SetBorder(std::move(border));
} }
void WindowMiniView::UpdateIconView() {
aura::Window* transient_root = wm::GetTransientRoot(source_window_);
// Prefer kAppIconKey over kWindowIconKey as the app icon is typically larger.
gfx::ImageSkia* icon = transient_root->GetProperty(aura::client::kAppIconKey);
if (!icon || icon->size().IsEmpty())
icon = transient_root->GetProperty(aura::client::kWindowIconKey);
if (!icon)
return;
if (!icon_view_) {
icon_view_ =
header_view_->AddChildViewAt(std::make_unique<views::ImageView>(), 0);
}
icon_view_->SetImage(ModifyIcon(icon));
icon_view_->SetSize(kIconSize);
}
gfx::Rect WindowMiniView::GetContentAreaBounds() const { gfx::Rect WindowMiniView::GetContentAreaBounds() const {
gfx::Rect bounds(GetContentsBounds()); gfx::Rect bounds(GetContentsBounds());
bounds.Inset(0, kHeaderHeightDp, 0, 0); bounds.Inset(0, kHeaderHeightDp, 0, 0);
...@@ -203,23 +220,4 @@ void WindowMiniView::OnWindowTitleChanged(aura::Window* window) { ...@@ -203,23 +220,4 @@ void WindowMiniView::OnWindowTitleChanged(aura::Window* window) {
title_label_->SetText(wm::GetTransientRoot(window)->GetTitle()); title_label_->SetText(wm::GetTransientRoot(window)->GetTitle());
} }
void WindowMiniView::UpdateIconView() {
aura::Window* transient_root = wm::GetTransientRoot(source_window_);
// Prefer kAppIconKey over kWindowIconKey as the app icon is typically larger.
gfx::ImageSkia* icon = transient_root->GetProperty(aura::client::kAppIconKey);
if (!icon || icon->size().IsEmpty())
icon = transient_root->GetProperty(aura::client::kWindowIconKey);
if (!icon)
return;
if (!icon_view_) {
icon_view_ =
header_view_->AddChildView(std::make_unique<views::ImageView>());
icon_view_->SetSize(kIconSize);
}
icon_view_->SetImage(gfx::ImageSkiaOperations::CreateResizedImage(
*icon, skia::ImageOperations::RESIZE_BEST, kIconSize));
}
} // namespace ash } // namespace ash
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define ASH_WM_WINDOW_MINI_VIEW_H_ #define ASH_WM_WINDOW_MINI_VIEW_H_
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "base/macros.h"
#include "base/scoped_observer.h" #include "base/scoped_observer.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/aura/window_observer.h" #include "ui/aura/window_observer.h"
...@@ -28,11 +27,18 @@ class WmHighlightItemBorder; ...@@ -28,11 +27,18 @@ class WmHighlightItemBorder;
class ASH_EXPORT WindowMiniView : public views::View, class ASH_EXPORT WindowMiniView : public views::View,
public aura::WindowObserver { public aura::WindowObserver {
public: public:
static constexpr int kHeaderHeightDp = 40; WindowMiniView(const WindowMiniView&) = delete;
WindowMiniView& operator=(const WindowMiniView&) = delete;
~WindowMiniView() override; ~WindowMiniView() override;
// Sets the visiblity of |backdrop_view_|. Creates it if it is null. static constexpr int kHeaderHeightDp = 40;
// The size in dp of the window icon shown on the alt-tab/overview window next
// to the title.
static constexpr gfx::Size kIconSize = gfx::Size(24, 24);
// Padding between header items.
static constexpr int kHeaderPaddingDp = 12;
// Sets the visibility of |backdrop_view_|. Creates it if it is null.
void SetBackdropVisibility(bool visible); void SetBackdropVisibility(bool visible);
// Creates or deletes |preview_view_| as needed. // Creates or deletes |preview_view_| as needed.
...@@ -46,12 +52,17 @@ class ASH_EXPORT WindowMiniView : public views::View, ...@@ -46,12 +52,17 @@ class ASH_EXPORT WindowMiniView : public views::View,
views::View* header_view() { return header_view_; } views::View* header_view() { return header_view_; }
views::Label* title_label() const { return title_label_; } views::Label* title_label() const { return title_label_; }
views::ImageView* icon_view() { return icon_view_; }
views::View* backdrop_view() { return backdrop_view_; } views::View* backdrop_view() { return backdrop_view_; }
WindowPreviewView* preview_view() const { return preview_view_; } WindowPreviewView* preview_view() const { return preview_view_; }
protected: protected:
explicit WindowMiniView(aura::Window* source_window); explicit WindowMiniView(aura::Window* source_window);
// Updates the icon view by creating it if necessary, and grabbing the correct
// image from |source_window_|.
void UpdateIconView();
WmHighlightItemBorder* border_ptr() { return border_ptr_; } WmHighlightItemBorder* border_ptr() { return border_ptr_; }
// Returns the bounds where the backdrop and preview should go. // Returns the bounds where the backdrop and preview should go.
...@@ -62,6 +73,9 @@ class ASH_EXPORT WindowMiniView : public views::View, ...@@ -62,6 +73,9 @@ class ASH_EXPORT WindowMiniView : public views::View,
virtual int GetMargin() const; virtual int GetMargin() const;
virtual gfx::Rect GetHeaderBounds() const; virtual gfx::Rect GetHeaderBounds() const;
virtual gfx::Size GetPreviewViewSize() const; virtual gfx::Size GetPreviewViewSize() const;
// Allows subclasses to resize/add shadow to the image that will appear as the
// icon. Defaults to do resize the image to |kIconSize|.
virtual gfx::ImageSkia ModifyIcon(gfx::ImageSkia* image) const;
// views::View: // views::View:
void Layout() override; void Layout() override;
...@@ -75,10 +89,6 @@ class ASH_EXPORT WindowMiniView : public views::View, ...@@ -75,10 +89,6 @@ class ASH_EXPORT WindowMiniView : public views::View,
void OnWindowTitleChanged(aura::Window* window) override; void OnWindowTitleChanged(aura::Window* window) override;
private: private:
// Updates the icon view by creating it if necessary, and grabbing the correct
// image from |source_window_|.
void UpdateIconView();
// The window this class is meant to be a header for. This class also may // The window this class is meant to be a header for. This class also may
// optionally show a mirrored view of this window. // optionally show a mirrored view of this window.
aura::Window* source_window_; aura::Window* source_window_;
...@@ -100,8 +110,6 @@ class ASH_EXPORT WindowMiniView : public views::View, ...@@ -100,8 +110,6 @@ class ASH_EXPORT WindowMiniView : public views::View,
WindowPreviewView* preview_view_ = nullptr; WindowPreviewView* preview_view_ = nullptr;
ScopedObserver<aura::Window, aura::WindowObserver> window_observer_{this}; ScopedObserver<aura::Window, aura::WindowObserver> window_observer_{this};
DISALLOW_COPY_AND_ASSIGN(WindowMiniView);
}; };
} // namespace ash } // namespace ash
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment