Commit e9f9ec35 authored by Ana Salazar's avatar Ana Salazar Committed by Commit Bot

Cros: Fix blurry icon on long press

Bug: 989820
Change-Id: Ia64921ca30d66e8f0bcbfff33ffdb0cbdf71e303
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2026595
Commit-Queue: Ana Salazar <anasalazar@chromium.org>
Reviewed-by: default avatarToni Baržić <tbarzic@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#739154}
parent 691d665b
...@@ -352,14 +352,16 @@ void ShelfAppButton::SetImage(const gfx::ImageSkia& image) { ...@@ -352,14 +352,16 @@ void ShelfAppButton::SetImage(const gfx::ImageSkia& image) {
if (image.isNull()) { if (image.isNull()) {
// TODO: need an empty image. // TODO: need an empty image.
icon_view_->SetImage(image); icon_view_->SetImage(image);
icon_image_ = gfx::ImageSkia();
return; return;
} }
icon_image_ = image;
const int icon_size = ShelfConfig::Get()->button_icon_size(); const int icon_size = ShelfConfig::Get()->button_icon_size() * icon_scale_;
// Resize the image maintaining our aspect ratio. // Resize the image maintaining our aspect ratio.
float aspect_ratio = float aspect_ratio = static_cast<float>(icon_image_.width()) /
static_cast<float>(image.width()) / static_cast<float>(image.height()); static_cast<float>(icon_image_.height());
int height = icon_size; int height = icon_size;
int width = static_cast<int>(aspect_ratio * height); int width = static_cast<int>(aspect_ratio * height);
if (width > icon_size) { if (width > icon_size) {
...@@ -367,13 +369,15 @@ void ShelfAppButton::SetImage(const gfx::ImageSkia& image) { ...@@ -367,13 +369,15 @@ void ShelfAppButton::SetImage(const gfx::ImageSkia& image) {
height = static_cast<int>(width / aspect_ratio); height = static_cast<int>(width / aspect_ratio);
} }
if (width == image.width() && height == image.height()) { const gfx::Size preferred_size(width, height);
if (image.size() == preferred_size) {
SetShadowedImage(image); SetShadowedImage(image);
return; return;
} }
SetShadowedImage(gfx::ImageSkiaOperations::CreateResizedImage( SetShadowedImage(gfx::ImageSkiaOperations::CreateResizedImage(
image, skia::ImageOperations::RESIZE_BEST, gfx::Size(width, height))); image, skia::ImageOperations::RESIZE_BEST, preferred_size));
} }
const gfx::ImageSkia& ShelfAppButton::GetImage() const { const gfx::ImageSkia& ShelfAppButton::GetImage() const {
...@@ -383,7 +387,7 @@ const gfx::ImageSkia& ShelfAppButton::GetImage() const { ...@@ -383,7 +387,7 @@ const gfx::ImageSkia& ShelfAppButton::GetImage() const {
void ShelfAppButton::AddState(State state) { void ShelfAppButton::AddState(State state) {
if (!(state_ & state)) { if (!(state_ & state)) {
state_ |= state; state_ |= state;
Layout(); InvalidateLayout();
if (state & STATE_ATTENTION) if (state & STATE_ATTENTION)
indicator_->ShowAttention(true); indicator_->ShowAttention(true);
...@@ -580,16 +584,13 @@ bool ShelfAppButton::OnMouseDragged(const ui::MouseEvent& event) { ...@@ -580,16 +584,13 @@ bool ShelfAppButton::OnMouseDragged(const ui::MouseEvent& event) {
return true; return true;
} }
void ShelfAppButton::Layout() { gfx::Rect ShelfAppButton::GetIconViewBounds(float icon_scale) {
int icon_size = ShelfConfig::Get()->button_icon_size() * icon_scale;
// TODO: Find out why there is an extra pixel of padding between each item // TODO: Find out why there is an extra pixel of padding between each item
// and the inner side of the shelf. // and the inner side of the shelf.
// clang-format off // clang-format off
int icon_padding = (ShelfConfig::Get()->hotseat_size() - int icon_padding = (ShelfConfig::Get()->hotseat_size() - icon_size) / 2;
ShelfConfig::Get()->button_icon_size()) / 2 - 1;
// clang-format on // clang-format on
const int icon_size = ShelfConfig::Get()->button_icon_size();
const int status_indicator_offet_from_shelf_edge =
ShelfConfig::Get()->status_indicator_offset_from_shelf_edge();
const gfx::Rect button_bounds(GetContentsBounds()); const gfx::Rect button_bounds(GetContentsBounds());
Shelf* shelf = shelf_view_->shelf(); Shelf* shelf = shelf_view_->shelf();
...@@ -605,21 +606,42 @@ void ShelfAppButton::Layout() { ...@@ -605,21 +606,42 @@ void ShelfAppButton::Layout() {
if (ShelfAlignment::kLeft == shelf->alignment()) if (ShelfAlignment::kLeft == shelf->alignment())
x_offset = button_bounds.width() - (icon_size + icon_padding); x_offset = button_bounds.width() - (icon_size + icon_padding);
// Center icon with respect to the secondary axis.
if (is_horizontal_shelf)
x_offset = std::max(0, button_bounds.width() - icon_width) / 2;
else
y_offset = std::max(0, button_bounds.height() - icon_height) / 2;
// Expand bounds to include shadows. // Expand bounds to include shadows.
gfx::Insets insets_shadows = gfx::ShadowValue::GetMargin(icon_shadows_); gfx::Insets insets_shadows = gfx::ShadowValue::GetMargin(icon_shadows_);
// Adjust offsets to center icon, not icon + shadow. // Center icon with respect to the secondary axis.
x_offset += (insets_shadows.left() - insets_shadows.right()) / 2; if (is_horizontal_shelf) {
y_offset += (insets_shadows.top() - insets_shadows.bottom()) / 2; x_offset =
std::max(0, button_bounds.width() - icon_width + insets_shadows.left() -
insets_shadows.right() + 1) /
2;
} else {
y_offset =
std::max(0, button_bounds.height() - icon_height +
insets_shadows.top() - insets_shadows.bottom() + 1) /
2;
}
gfx::Rect icon_view_bounds = gfx::Rect icon_view_bounds =
gfx::Rect(button_bounds.x() + x_offset, button_bounds.y() + y_offset, gfx::Rect(button_bounds.x() + x_offset, button_bounds.y() + y_offset,
icon_width, icon_height); icon_width, icon_height);
icon_view_bounds.Inset(insets_shadows);
// Icon size has been incorrect when running
// PanelLayoutManagerTest.PanelAlignmentSecondDisplay on valgrind bot, see
// http://crbug.com/234854.
DCHECK_LE(icon_width, icon_size);
DCHECK_LE(icon_height, icon_size);
return icon_view_bounds;
}
void ShelfAppButton::Layout() {
Shelf* shelf = shelf_view_->shelf();
gfx::Rect icon_view_bounds = GetIconViewBounds(icon_scale_);
const gfx::Rect button_bounds(GetContentsBounds());
const int status_indicator_offet_from_shelf_edge =
ShelfConfig::Get()->status_indicator_offset_from_shelf_edge();
icon_view_->SetBoundsRect(icon_view_bounds);
// The indicators should be aligned with the icon, not the icon + shadow. // The indicators should be aligned with the icon, not the icon + shadow.
gfx::Point indicator_midpoint = icon_view_bounds.CenterPoint(); gfx::Point indicator_midpoint = icon_view_bounds.CenterPoint();
if (is_notification_indicator_enabled_) { if (is_notification_indicator_enabled_) {
...@@ -629,16 +651,6 @@ void ShelfAppButton::Layout() { ...@@ -629,16 +651,6 @@ void ShelfAppButton::Layout() {
kNotificationIndicatorRadiusDip * 2)); kNotificationIndicatorRadiusDip * 2));
} }
icon_view_bounds.Inset(insets_shadows);
icon_view_bounds.AdjustToFit(gfx::Rect(size()));
icon_view_->SetBoundsRect(icon_view_bounds);
// Icon size has been incorrect when running
// PanelLayoutManagerTest.PanelAlignmentSecondDisplay on valgrind bot, see
// http://crbug.com/234854.
DCHECK_LE(icon_width, icon_size);
DCHECK_LE(icon_height, icon_size);
switch (shelf->alignment()) { switch (shelf->alignment()) {
case ShelfAlignment::kBottom: case ShelfAlignment::kBottom:
case ShelfAlignment::kBottomLocked: case ShelfAlignment::kBottomLocked:
...@@ -828,18 +840,37 @@ void ShelfAppButton::OnRippleTimer() { ...@@ -828,18 +840,37 @@ void ShelfAppButton::OnRippleTimer() {
GetInkDrop()->AnimateToState(views::InkDropState::ACTIVATED); GetInkDrop()->AnimateToState(views::InkDropState::ACTIVATED);
} }
gfx::Transform ShelfAppButton::GetScaleTransform(float icon_scale) {
gfx::RectF pre_scaling_bounds(GetIconViewBounds(1.0f));
gfx::RectF target_bounds(GetIconViewBounds(icon_scale));
return gfx::TransformBetweenRects(target_bounds, pre_scaling_bounds);
}
void ShelfAppButton::ScaleAppIcon(bool scale_up) { void ShelfAppButton::ScaleAppIcon(bool scale_up) {
StopObservingImplicitAnimations();
if (scale_up) {
icon_scale_ = kAppIconScale;
SetImage(icon_image_);
icon_view_->layer()->SetTransform(GetScaleTransform(kAppIconScale));
}
ui::ScopedLayerAnimationSettings settings(icon_view_->layer()->GetAnimator()); ui::ScopedLayerAnimationSettings settings(icon_view_->layer()->GetAnimator());
settings.SetTransitionDuration( settings.SetTransitionDuration(
base::TimeDelta::FromMilliseconds(kDragDropAppIconScaleTransitionMs)); base::TimeDelta::FromMilliseconds(kDragDropAppIconScaleTransitionMs));
if (scale_up) { if (scale_up) {
icon_view_->layer()->SetTransform(gfx::GetScaleTransform(
gfx::Rect(icon_view_->layer()->bounds().size()).CenterPoint(),
kAppIconScale));
} else {
icon_view_->layer()->SetTransform(gfx::Transform()); icon_view_->layer()->SetTransform(gfx::Transform());
} else {
// To avoid poor quality icons, update icon image with the correct scale
// after the transform animation is completed.
settings.AddObserver(this);
icon_view_->layer()->SetTransform(GetScaleTransform(kAppIconScale));
} }
} }
void ShelfAppButton::OnImplicitAnimationsCompleted() {
icon_scale_ = 1.0f;
SetImage(icon_image_);
icon_view_->layer()->SetTransform(gfx::Transform());
}
} // namespace ash } // namespace ash
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "ash/shelf/shelf_button.h" #include "ash/shelf/shelf_button.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/gfx/shadow_value.h" #include "ui/gfx/shadow_value.h"
#include "ui/views/animation/ink_drop_observer.h" #include "ui/views/animation/ink_drop_observer.h"
#include "ui/views/animation/ink_drop_state.h" #include "ui/views/animation/ink_drop_state.h"
...@@ -23,7 +24,8 @@ class ShelfView; ...@@ -23,7 +24,8 @@ class ShelfView;
// Button used for app shortcuts on the shelf.. // Button used for app shortcuts on the shelf..
class ASH_EXPORT ShelfAppButton : public ShelfButton, class ASH_EXPORT ShelfAppButton : public ShelfButton,
public views::InkDropObserver { public views::InkDropObserver,
public ui::ImplicitAnimationObserver {
public: public:
static const char kViewClassName[]; static const char kViewClassName[];
...@@ -113,6 +115,9 @@ class ASH_EXPORT ShelfAppButton : public ShelfButton, ...@@ -113,6 +115,9 @@ class ASH_EXPORT ShelfAppButton : public ShelfButton,
std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override; std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override;
std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override; std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override;
// ui::ImplicitAnimationObserver:
void OnImplicitAnimationsCompleted() override;
// Sets the icon image with a shadow. // Sets the icon image with a shadow.
void SetShadowedImage(const gfx::ImageSkia& bitmap); void SetShadowedImage(const gfx::ImageSkia& bitmap);
...@@ -137,6 +142,13 @@ class ASH_EXPORT ShelfAppButton : public ShelfButton, ...@@ -137,6 +142,13 @@ class ASH_EXPORT ShelfAppButton : public ShelfButton,
// normal size. // normal size.
void ScaleAppIcon(bool scale_up); void ScaleAppIcon(bool scale_up);
// Calculates the icon bounds for an icon scaled by |icon_scale|.
gfx::Rect GetIconViewBounds(float icon_scale);
// Calculates the transform between the icon scaled by |icon_scale| and the
// normal size icon.
gfx::Transform GetScaleTransform(float icon_scale);
// The icon part of a button can be animated independently of the rest. // The icon part of a button can be animated independently of the rest.
views::ImageView* icon_view_; views::ImageView* icon_view_;
...@@ -163,6 +175,12 @@ class ASH_EXPORT ShelfAppButton : public ShelfButton, ...@@ -163,6 +175,12 @@ class ASH_EXPORT ShelfAppButton : public ShelfButton,
// Whether the notification indicator is enabled. // Whether the notification indicator is enabled.
const bool is_notification_indicator_enabled_; const bool is_notification_indicator_enabled_;
// The bitmap image for this app button.
gfx::ImageSkia icon_image_;
// The scaling factor for displaying the app icon.
float icon_scale_ = 1.0f;
// A timer to defer showing drag UI when the shelf button is pressed. // A timer to defer showing drag UI when the shelf button is pressed.
base::OneShotTimer drag_timer_; base::OneShotTimer drag_timer_;
......
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