1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/toolbar/wrench_icon_painter.h"
9 #include "grit/theme_resources.h"
10 #include "ui/base/theme_provider.h"
11 #include "ui/gfx/animation/multi_animation.h"
12 #include "ui/gfx/canvas.h"
13 #include "ui/gfx/geometry/rect.h"
14 #include "ui/gfx/image/image_skia.h"
18 // The wrench icon is made up of this many bars stacked vertically.
19 const int kBarCount
= 3;
21 // |value| is the animation progress from 0 to 1. |index| is the index of the
22 // bar being drawn. This function returns a new progress value (from 0 to 1)
23 // such that bars appear staggered.
24 double GetStaggeredValue(double value
, int index
) {
25 // When animating the wrench icon's bars the bars are staggered by this
27 const double kStaggerFactor
= 0.15;
28 double maxStaggeredValue
= 1.0 - (kBarCount
- 1) * kStaggerFactor
;
29 double staggeredValue
= (value
- kStaggerFactor
* index
) / maxStaggeredValue
;
30 return std::min(1.0, std::max(0.0, staggeredValue
));
35 WrenchIconPainter::WrenchIconPainter(Delegate
* delegate
)
36 : delegate_(delegate
),
37 severity_(SEVERITY_NONE
) {
40 WrenchIconPainter::~WrenchIconPainter() {}
42 void WrenchIconPainter::SetSeverity(Severity severity
, bool animate
) {
43 if (severity_
== severity
)
47 delegate_
->ScheduleWrenchIconPaint();
49 if (severity_
== SEVERITY_NONE
|| !animate
)
52 gfx::MultiAnimation::Parts parts
;
53 // Animate the bars left to right.
54 parts
.push_back(gfx::MultiAnimation::Part(1300, gfx::Tween::LINEAR
));
55 // Fade out animation.
56 parts
.push_back(gfx::MultiAnimation::Part(1000, gfx::Tween::EASE_IN
));
57 // Again, animate the bars left to right.
58 parts
.push_back(gfx::MultiAnimation::Part(1300, gfx::Tween::LINEAR
));
61 new gfx::MultiAnimation(parts
, base::TimeDelta::FromMilliseconds(40)));
62 animation_
->set_delegate(this);
63 animation_
->set_continuous(false);
67 void WrenchIconPainter::Paint(gfx::Canvas
* canvas
,
68 ui::ThemeProvider
* theme_provider
,
69 const gfx::Rect
& rect
,
70 BezelType bezel_type
) {
71 gfx::Point center
= rect
.CenterPoint();
79 resource_id
= IDR_TOOLBAR_BEZEL_HOVER
;
82 resource_id
= IDR_TOOLBAR_BEZEL_PRESSED
;
87 gfx::ImageSkia
* image
= theme_provider
->GetImageSkiaNamed(resource_id
);
88 canvas
->DrawImageInt(*image
,
89 center
.x() - image
->width() / 2,
90 center
.y() - image
->height() / 2);
93 // The bars with no color.
95 gfx::ImageSkia
* image
= theme_provider
->GetImageSkiaNamed(IDR_TOOLS_BAR
);
96 int x
= center
.x() - image
->width() / 2;
97 int y
= center
.y() - image
->height() * kBarCount
/ 2;
98 for (int i
= 0; i
< kBarCount
; ++i
) {
99 canvas
->DrawImageInt(*image
, x
, y
);
100 y
+= image
->height();
104 // The bars with color based on severity.
105 int severity_image_id
= GetCurrentSeverityImageID();
106 if (severity_image_id
) {
107 gfx::ImageSkia
* image
=
108 theme_provider
->GetImageSkiaNamed(severity_image_id
);
109 int x
= center
.x() - image
->width() / 2;
110 int y
= center
.y() - image
->height() * kBarCount
/ 2;
111 for (int i
= 0; i
< kBarCount
; ++i
) {
113 int width
= image
->width();
115 if (animation_
&& animation_
->is_animating()) {
116 if (animation_
->current_part_index() % 2 == 1) {
118 int alpha
= animation_
->CurrentValueBetween(0xFF, 0);
121 paint
.setAlpha(alpha
);
123 // Stagger the widths.
124 width
= image
->width() *
125 GetStaggeredValue(animation_
->GetCurrentValue(), i
);
131 canvas
->DrawImageInt(*image
, 0, 0, width
, image
->height(),
132 x
, y
, width
, image
->height(), false, paint
);
133 y
+= image
->height();
137 if (!badge_
.isNull())
138 canvas
->DrawImageInt(badge_
, 0, 0);
141 void WrenchIconPainter::AnimationProgressed(const gfx::Animation
* animation
) {
142 delegate_
->ScheduleWrenchIconPaint();
145 int WrenchIconPainter::GetCurrentSeverityImageID() const {
150 return IDR_TOOLS_BAR_LOW
;
151 case SEVERITY_MEDIUM
:
152 return IDR_TOOLS_BAR_MEDIUM
;
154 return IDR_TOOLS_BAR_HIGH
;