Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1853)

Unified Diff: ash/common/shelf/shelf_button.cc

Issue 2727073002: Preliminary cleanup of ShelfButton activity/status indicator. (Closed)
Patch Set: rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ash/common/shelf/shelf_button.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ash/common/shelf/shelf_button.cc
diff --git a/ash/common/shelf/shelf_button.cc b/ash/common/shelf/shelf_button.cc
index ff2e786a1d0a3cfbdbba3b942437fd1976c13731..b39fa9c2f785d3bd2c4c23ae58b1dd20de0d3ccc 100644
--- a/ash/common/shelf/shelf_button.cc
+++ b/ash/common/shelf/shelf_button.cc
@@ -21,6 +21,7 @@
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/image/image_skia_operations.h"
+#include "ui/gfx/scoped_canvas.h"
#include "ui/gfx/skbitmap_operations.h"
#include "ui/views/animation/ink_drop_impl.h"
#include "ui/views/animation/square_ink_drop_ripple.h"
@@ -28,18 +29,12 @@
namespace {
-// Size of the bar. This is along the opposite axis of the shelf. For example,
-// if the shelf is aligned horizontally then this is the height of the bar.
-const int kBarSize = 3;
const int kIconSize = 32;
const int kAttentionThrobDurationMS = 800;
const int kMaxAnimationSeconds = 10;
const int kIndicatorOffsetFromBottom = 2;
-const int kIndicatorRadius = 2;
+const int kIndicatorRadiusDip = 2;
const SkColor kIndicatorColor = SK_ColorWHITE;
-// Canvas scale to ensure that the activity indicator is not pixelated even at
-// the highest possible device scale factors.
-const int kIndicatorCanvasScale = 5;
// Shelf item ripple constants.
const int kInkDropSmallSize = 48;
@@ -50,17 +45,6 @@ const int kInkDropLargeSize = 60;
const int kIconPaddingHorizontal = 7;
const int kIconPaddingVertical = 8;
-// Paints an activity indicator on |canvas| whose |size| is specified in DIP.
-void PaintIndicatorOnCanvas(gfx::Canvas* canvas, const gfx::Size& size) {
- cc::PaintFlags flags;
- flags.setAntiAlias(true);
- flags.setColor(kIndicatorColor);
- canvas->DrawCircle(
- gfx::Point(size.width() / 2,
- size.height() - kIndicatorOffsetFromBottom - kIndicatorRadius),
- kIndicatorRadius, flags);
-}
-
// Simple AnimationDelegate that owns a single ThrobAnimation instance to
// keep all Draw Attention animations in sync.
class ShelfButtonAnimation : public gfx::AnimationDelegate {
@@ -86,7 +70,14 @@ class ShelfButtonAnimation : public gfx::AnimationDelegate {
animation_.Stop();
}
- int GetAlpha() { return GetThrobAnimation().CurrentValueBetween(0, 255); }
+ bool HasObserver(Observer* observer) const {
+ return observers_.HasObserver(observer);
+ }
+
+ SkAlpha GetAlpha() {
+ return GetThrobAnimation().CurrentValueBetween(SK_AlphaTRANSPARENT,
+ SK_AlphaOPAQUE);
+ }
double GetAnimation() { return GetThrobAnimation().GetCurrentValue(); }
@@ -127,111 +118,71 @@ class ShelfButtonAnimation : public gfx::AnimationDelegate {
namespace ash {
////////////////////////////////////////////////////////////////////////////////
-// ShelfButton::BarView
+// ShelfButton::AppStatusIndicatorView
-class ShelfButton::BarView : public views::ImageView,
- public ShelfButtonAnimation::Observer {
+class ShelfButton::AppStatusIndicatorView
+ : public views::View,
+ public ShelfButtonAnimation::Observer {
public:
- BarView(WmShelf* wm_shelf)
- : wm_shelf_(wm_shelf),
- show_attention_(false),
- animation_end_time_(base::TimeTicks()),
- animating_(false) {
+ AppStatusIndicatorView()
+ : show_attention_(false), animation_end_time_(base::TimeTicks()) {
// Make sure the events reach the parent view for handling.
set_can_process_events_within_subtree(false);
}
- ~BarView() override {
- if (show_attention_)
- ShelfButtonAnimation::GetInstance()->RemoveObserver(this);
+ ~AppStatusIndicatorView() override {
+ ShelfButtonAnimation::GetInstance()->RemoveObserver(this);
}
// views::View:
void OnPaint(gfx::Canvas* canvas) override {
+ gfx::ScopedCanvas scoped(canvas);
if (show_attention_) {
- int alpha =
- animating_ ? ShelfButtonAnimation::GetInstance()->GetAlpha() : 255;
+ SkAlpha alpha = ShelfButtonAnimation::GetInstance()->HasObserver(this)
+ ? ShelfButtonAnimation::GetInstance()->GetAlpha()
+ : SK_AlphaOPAQUE;
canvas->SaveLayerAlpha(alpha);
- views::ImageView::OnPaint(canvas);
- canvas->Restore();
- } else {
- views::ImageView::OnPaint(canvas);
}
+
+ DCHECK_EQ(width(), height());
+ DCHECK_EQ(kIndicatorRadiusDip, width() / 2);
+ cc::PaintFlags flags;
+ flags.setColor(kIndicatorColor);
+ flags.setFlags(cc::PaintFlags::kAntiAlias_Flag);
+ canvas->DrawCircle(gfx::Point(width() / 2, height() / 2),
+ kIndicatorRadiusDip, flags);
}
// ShelfButtonAnimation::Observer
void AnimationProgressed() override {
- UpdateBounds();
+ UpdateAnimating();
SchedulePaint();
}
- void SetBarBoundsRect(const gfx::Rect& bounds) {
- base_bounds_ = bounds;
- UpdateBounds();
- }
-
void ShowAttention(bool show) {
- if (show_attention_ != show) {
- show_attention_ = show;
- if (show_attention_) {
- animating_ = true;
- animation_end_time_ =
- base::TimeTicks::Now() +
- base::TimeDelta::FromSeconds(kMaxAnimationSeconds);
- ShelfButtonAnimation::GetInstance()->AddObserver(this);
- } else {
- animating_ = false;
- ShelfButtonAnimation::GetInstance()->RemoveObserver(this);
- }
- }
- UpdateBounds();
- }
+ if (show_attention_ == show)
+ return;
- private:
- void UpdateBounds() {
- gfx::Rect bounds = base_bounds_;
+ show_attention_ = show;
if (show_attention_) {
- // Scale from .35 to 1.0 of the total width (which is wider than the
- // visible width of the image), so the animation "rests" briefly at full
- // visible width. Cap bounds length at kIconSize to prevent visual
- // flutter while centering bar within further expanding bounds.
- double animation =
- animating_ ? ShelfButtonAnimation::GetInstance()->GetAnimation()
- : 1.0;
- double scale = .35 + .65 * animation;
- if (wm_shelf_->IsHorizontalAlignment()) {
- int width = base_bounds_.width() * scale;
- bounds.set_width(std::min(width, kIconSize));
- int x_offset = (base_bounds_.width() - bounds.width()) / 2;
- bounds.set_x(base_bounds_.x() + x_offset);
- UpdateAnimating(bounds.width() == kIconSize);
- } else {
- int height = base_bounds_.height() * scale;
- bounds.set_height(std::min(height, kIconSize));
- int y_offset = (base_bounds_.height() - bounds.height()) / 2;
- bounds.set_y(base_bounds_.y() + y_offset);
- UpdateAnimating(bounds.height() == kIconSize);
- }
+ animation_end_time_ = base::TimeTicks::Now() +
+ base::TimeDelta::FromSeconds(kMaxAnimationSeconds);
+ ShelfButtonAnimation::GetInstance()->AddObserver(this);
+ } else {
+ ShelfButtonAnimation::GetInstance()->RemoveObserver(this);
}
- SetBoundsRect(bounds);
}
- void UpdateAnimating(bool max_length) {
- if (!max_length)
- return;
- if (base::TimeTicks::Now() > animation_end_time_) {
- animating_ = false;
+ private:
+ void UpdateAnimating() {
+ if (base::TimeTicks::Now() > animation_end_time_)
ShelfButtonAnimation::GetInstance()->RemoveObserver(this);
- }
}
- WmShelf* wm_shelf_;
bool show_attention_;
base::TimeTicks animation_end_time_; // For attention throbbing underline.
- bool animating_; // Is time-limited attention animation running?
- gfx::Rect base_bounds_;
- DISALLOW_COPY_AND_ASSIGN(BarView);
+ DISALLOW_COPY_AND_ASSIGN(AppStatusIndicatorView);
};
////////////////////////////////////////////////////////////////////////////////
@@ -245,7 +196,7 @@ ShelfButton::ShelfButton(InkDropButtonListener* listener, ShelfView* shelf_view)
listener_(listener),
shelf_view_(shelf_view),
icon_view_(new views::ImageView()),
- bar_(new BarView(shelf_view->wm_shelf())),
+ indicator_(new AppStatusIndicatorView()),
state_(STATE_NORMAL),
destroyed_flag_(nullptr) {
SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
@@ -268,7 +219,7 @@ ShelfButton::ShelfButton(InkDropButtonListener* listener, ShelfView* shelf_view)
// Do not make this interactive, so that events are sent to ShelfView.
icon_view_->set_can_process_events_within_subtree(false);
- AddChildView(bar_);
+ AddChildView(indicator_);
AddChildView(icon_view_);
}
@@ -317,7 +268,7 @@ void ShelfButton::AddState(State state) {
state_ |= state;
Layout();
if (state & STATE_ATTENTION)
- bar_->ShowAttention(true);
+ indicator_->ShowAttention(true);
}
}
@@ -326,7 +277,7 @@ void ShelfButton::ClearState(State state) {
state_ &= ~state;
Layout();
if (state & STATE_ATTENTION)
- bar_->ShowAttention(false);
+ indicator_->ShowAttention(false);
}
}
@@ -406,17 +357,11 @@ void ShelfButton::Layout() {
if (SHELF_ALIGNMENT_LEFT == wm_shelf->GetAlignment())
x_offset = button_bounds.width() - (kIconSize + icon_pad);
- // Center icon with respect to the secondary axis, and ensure
- // that the icon doesn't occlude the bar highlight.
- if (is_horizontal_shelf) {
+ // Center icon with respect to the secondary axis.
+ if (is_horizontal_shelf)
x_offset = std::max(0, button_bounds.width() - icon_width) / 2;
- if (y_offset + icon_height + kBarSize > button_bounds.height())
- icon_height = button_bounds.height() - (y_offset + kBarSize);
- } else {
+ else
y_offset = std::max(0, button_bounds.height() - icon_height) / 2;
- if (x_offset + icon_width + kBarSize > button_bounds.width())
- icon_width = button_bounds.width() - (x_offset + kBarSize);
- }
// Expand bounds to include shadows.
gfx::Insets insets_shadows = gfx::ShadowValue::GetMargin(icon_shadows_);
@@ -426,6 +371,8 @@ void ShelfButton::Layout() {
gfx::Rect icon_view_bounds =
gfx::Rect(button_bounds.x() + x_offset, button_bounds.y() + y_offset,
icon_width, icon_height);
+ // The indicator should be aligned with the icon, not the icon + shadow.
+ gfx::Point indicator_midpoint = icon_view_bounds.CenterPoint();
icon_view_bounds.Inset(insets_shadows);
icon_view_bounds.AdjustToFit(gfx::Rect(size()));
icon_view_->SetBoundsRect(icon_view_bounds);
@@ -436,7 +383,25 @@ void ShelfButton::Layout() {
DCHECK_LE(icon_width, kIconSize);
DCHECK_LE(icon_height, kIconSize);
- bar_->SetBarBoundsRect(button_bounds);
+ switch (wm_shelf->GetAlignment()) {
+ case SHELF_ALIGNMENT_BOTTOM:
+ case SHELF_ALIGNMENT_BOTTOM_LOCKED:
+ indicator_midpoint.set_y(button_bounds.bottom() - kIndicatorRadiusDip -
+ kIndicatorOffsetFromBottom);
+ break;
+ case SHELF_ALIGNMENT_LEFT:
+ indicator_midpoint.set_x(button_bounds.x() + kIndicatorRadiusDip +
+ kIndicatorOffsetFromBottom);
+ break;
+ case SHELF_ALIGNMENT_RIGHT:
+ indicator_midpoint.set_x(button_bounds.right() - kIndicatorRadiusDip -
+ kIndicatorOffsetFromBottom);
+ break;
+ }
+
+ gfx::Rect indicator_bounds(indicator_midpoint, gfx::Size());
+ indicator_bounds.Inset(gfx::Insets(-kIndicatorRadiusDip));
+ indicator_->SetBoundsRect(indicator_bounds);
UpdateState();
}
@@ -519,7 +484,10 @@ void ShelfButton::NotifyClick(const ui::Event& event) {
}
void ShelfButton::UpdateState() {
- UpdateBar();
+ indicator_->SetVisible(!(state_ & STATE_HIDDEN) &&
+ (state_ & STATE_ACTIVE || state_ & STATE_ATTENTION ||
+ state_ & STATE_RUNNING));
+
const bool is_horizontal_shelf =
shelf_view_->wm_shelf()->IsHorizontalAlignment();
icon_view_->SetHorizontalAlignment(is_horizontal_shelf
@@ -531,47 +499,4 @@ void ShelfButton::UpdateState() {
SchedulePaint();
}
-void ShelfButton::UpdateBar() {
- bool draw_bar = !(state_ & STATE_HIDDEN) &&
- (state_ & STATE_ACTIVE || state_ & STATE_ATTENTION ||
- state_ & STATE_RUNNING);
-
- if (draw_bar) {
- WmShelf* wm_shelf = shelf_view_->wm_shelf();
- gfx::ImageSkia image;
- if (wm_shelf->IsVisible()) {
- gfx::Size size(kShelfButtonSize, GetShelfConstant(SHELF_SIZE));
- gfx::Canvas canvas(size, kIndicatorCanvasScale, true /* is_opaque */);
- PaintIndicatorOnCanvas(&canvas, size);
- image = gfx::ImageSkia(canvas.ExtractImageRep());
- }
- ShelfAlignment shelf_alignment = wm_shelf->GetAlignment();
- if (!wm_shelf->IsHorizontalAlignment()) {
- image = gfx::ImageSkiaOperations::CreateRotatedImage(
- image, shelf_alignment == SHELF_ALIGNMENT_LEFT
- ? SkBitmapOperations::ROTATION_90_CW
- : SkBitmapOperations::ROTATION_270_CW);
- }
- bar_->SetImage(image);
- switch (shelf_alignment) {
- case SHELF_ALIGNMENT_BOTTOM:
- case SHELF_ALIGNMENT_BOTTOM_LOCKED:
- bar_->SetHorizontalAlignment(views::ImageView::CENTER);
- bar_->SetVerticalAlignment(views::ImageView::TRAILING);
- break;
- case SHELF_ALIGNMENT_LEFT:
- bar_->SetHorizontalAlignment(views::ImageView::LEADING);
- bar_->SetVerticalAlignment(views::ImageView::CENTER);
- break;
- case SHELF_ALIGNMENT_RIGHT:
- bar_->SetHorizontalAlignment(views::ImageView::TRAILING);
- bar_->SetVerticalAlignment(views::ImageView::CENTER);
- break;
- }
- bar_->SchedulePaint();
- }
-
- bar_->SetVisible(draw_bar);
-}
-
} // namespace ash
« no previous file with comments | « ash/common/shelf/shelf_button.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698