Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / toolbar / wrench_icon_painter.cc
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.
4
5 #include "chrome/browser/ui/toolbar/wrench_icon_painter.h"
6
7 #include <algorithm>
8
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/image/image_skia.h"
14 #include "ui/gfx/rect.h"
15
16 namespace {
17
18 // The wrench icon is made up of this many bars stacked vertically.
19 const int kBarCount = 3;
20
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
26   // factor.
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));
31 }
32
33 }  // namespace
34
35 WrenchIconPainter::WrenchIconPainter(Delegate* delegate)
36     : delegate_(delegate),
37       severity_(SEVERITY_NONE) {
38 }
39
40 WrenchIconPainter::~WrenchIconPainter() {}
41
42 void WrenchIconPainter::SetSeverity(Severity severity, bool animate) {
43   if (severity_ == severity)
44     return;
45
46   severity_ = severity;
47   delegate_->ScheduleWrenchIconPaint();
48   animation_.reset();
49   if (severity_ == SEVERITY_NONE || !animate)
50     return;
51
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));
59
60   animation_.reset(
61       new gfx::MultiAnimation(parts, base::TimeDelta::FromMilliseconds(40)));
62   animation_->set_delegate(this);
63   animation_->set_continuous(false);
64   animation_->Start();
65 }
66
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();
72
73   // Bezel.
74   if (bezel_type != BEZEL_NONE) {
75     gfx::ImageSkia* image = theme_provider->GetImageSkiaNamed(
76         bezel_type == BEZEL_HOVER ? IDR_TOOLBAR_BEZEL_HOVER
77                                   : IDR_TOOLBAR_BEZEL_PRESSED);
78     canvas->DrawImageInt(*image,
79                          center.x() - image->width() / 2,
80                          center.y() - image->height() / 2);
81   }
82
83   // The bars with no color.
84   {
85     gfx::ImageSkia* image = theme_provider->GetImageSkiaNamed(IDR_TOOLS_BAR);
86     int x = center.x() - image->width() / 2;
87     int y = center.y() - image->height() * kBarCount / 2;
88     for (int i = 0; i < kBarCount; ++i) {
89       canvas->DrawImageInt(*image, x, y);
90       y += image->height();
91     }
92   }
93
94   // The bars with color based on severity.
95   int severity_image_id = GetCurrentSeverityImageID();
96   if (severity_image_id) {
97     gfx::ImageSkia* image =
98         theme_provider->GetImageSkiaNamed(severity_image_id);
99     int x = center.x() - image->width() / 2;
100     int y = center.y() - image->height() * kBarCount / 2;
101     for (int i = 0; i < kBarCount; ++i) {
102       SkPaint paint;
103       int width = image->width();
104
105       if (animation_ && animation_->is_animating()) {
106         if (animation_->current_part_index() % 2 == 1) {
107           // Fade out.
108           int alpha = animation_->CurrentValueBetween(0xFF, 0);
109           if (alpha == 0)
110             continue;
111           paint.setAlpha(alpha);
112         } else {
113           // Stagger the widths.
114           width = image->width() *
115                   GetStaggeredValue(animation_->GetCurrentValue(), i);
116           if (width == 0)
117             continue;
118         }
119       }
120
121       canvas->DrawImageInt(*image, 0, 0, width, image->height(),
122                             x, y, width, image->height(), false, paint);
123       y += image->height();
124     }
125   }
126
127   if (!badge_.isNull())
128     canvas->DrawImageInt(badge_, 0, 0);
129 }
130
131 void WrenchIconPainter::AnimationProgressed(const gfx::Animation* animation) {
132   delegate_->ScheduleWrenchIconPaint();
133 }
134
135 int WrenchIconPainter::GetCurrentSeverityImageID() const {
136   switch (severity_) {
137     case SEVERITY_NONE:
138       return 0;
139     case SEVERITY_LOW:
140       return IDR_TOOLS_BAR_LOW;
141     case SEVERITY_MEDIUM:
142       return IDR_TOOLS_BAR_MEDIUM;
143     case SEVERITY_HIGH:
144       return IDR_TOOLS_BAR_HIGH;
145   }
146   NOTREACHED();
147   return 0;
148 }