1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Use of this source code is governed by a BSD-style license that can be
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// found in the LICENSE file.
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/views/controls/progress_bar.h"
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include <algorithm>
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include <string>
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "base/logging.h"
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "third_party/skia/include/core/SkPaint.h"
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "third_party/skia/include/core/SkXfermode.h"
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "third_party/skia/include/effects/SkGradientShader.h"
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/accessibility/ax_view_state.h"
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/gfx/canvas.h"
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernamespace {
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Progress bar's border width.
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst int kBorderWidth = 1;
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Corner radius for the progress bar's border.
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst int kCornerRadius = 2;
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// The width of the highlight at the right of the progress bar.
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst int kHighlightWidth = 18;
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst SkColor kBackgroundColor = SkColorSetRGB(230, 230, 230);
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst SkColor kBackgroundBorderColor = SkColorSetRGB(208, 208, 208);
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst SkColor kBarBorderColor = SkColorSetRGB(65, 137, 237);
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst SkColor kBarTopColor = SkColorSetRGB(110, 188, 249);
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst SkColor kBarColorStart = SkColorSetRGB(86, 167, 247);
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst SkColor kBarColorEnd = SkColorSetRGB(76, 148, 245);
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst SkColor kBarHighlightEnd = SkColorSetRGB(114, 206, 251);
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst SkColor kDisabledBarBorderColor = SkColorSetRGB(191, 191, 191);
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst SkColor kDisabledBarColorStart = SkColorSetRGB(224, 224, 224);
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst SkColor kDisabledBarColorEnd = SkColorSetRGB(212, 212, 212);
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid AddRoundRectPathWithPadding(int x, int y,
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                 int w, int h,
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                 int corner_radius,
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                 SkScalar padding,
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                 SkPath* path) {
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  DCHECK(path);
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  SkRect rect;
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  rect.set(
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      SkIntToScalar(x) + padding, SkIntToScalar(y) + padding,
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      SkIntToScalar(x + w) - padding, SkIntToScalar(y + h) - padding);
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  path->addRoundRect(
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      rect,
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      SkIntToScalar(corner_radius) - padding,
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      SkIntToScalar(corner_radius) - padding);
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid AddRoundRectPath(int x, int y,
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                      int w, int h,
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                      int corner_radius,
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                      SkPath* path) {
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  AddRoundRectPathWithPadding(x, y, w, h, corner_radius, SK_ScalarHalf, path);
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid FillRoundRect(gfx::Canvas* canvas,
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   int x, int y,
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   int w, int h,
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   int corner_radius,
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   const SkColor colors[],
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   const SkScalar points[],
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   int count,
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   bool gradient_horizontal) {
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  SkPath path;
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  AddRoundRectPath(x, y, w, h, corner_radius, &path);
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  SkPaint paint;
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  paint.setStyle(SkPaint::kFill_Style);
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  paint.setFlags(SkPaint::kAntiAlias_Flag);
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  SkPoint p[2];
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  p[0].iset(x, y);
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  if (gradient_horizontal) {
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    p[1].iset(x + w, y);
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  } else {
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    p[1].iset(x, y + h);
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  }
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  skia::RefPtr<SkShader> s = skia::AdoptRef(SkGradientShader::CreateLinear(
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      p, colors, points, count, SkShader::kClamp_TileMode));
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  paint.setShader(s.get());
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  canvas->DrawPath(path, paint);
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid FillRoundRect(gfx::Canvas* canvas,
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   int x, int y,
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   int w, int h,
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   int corner_radius,
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   SkColor gradient_start_color,
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   SkColor gradient_end_color,
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   bool gradient_horizontal) {
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  if (gradient_start_color != gradient_end_color) {
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    SkColor colors[2] = { gradient_start_color, gradient_end_color };
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    FillRoundRect(canvas, x, y, w, h, corner_radius,
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  colors, NULL, 2, gradient_horizontal);
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  } else {
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    SkPath path;
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    AddRoundRectPath(x, y, w, h, corner_radius, &path);
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    SkPaint paint;
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    paint.setStyle(SkPaint::kFill_Style);
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    paint.setFlags(SkPaint::kAntiAlias_Flag);
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    paint.setColor(gradient_start_color);
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    canvas->DrawPath(path, paint);
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  }
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid StrokeRoundRect(gfx::Canvas* canvas,
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                     int x, int y,
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                     int w, int h,
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                     int corner_radius,
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                     SkColor stroke_color,
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                     int stroke_width) {
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  SkPath path;
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  AddRoundRectPath(x, y, w, h, corner_radius, &path);
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  SkPaint paint;
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  paint.setShader(NULL);
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  paint.setColor(stroke_color);
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  paint.setStyle(SkPaint::kStroke_Style);
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  paint.setFlags(SkPaint::kAntiAlias_Flag);
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  paint.setStrokeWidth(SkIntToScalar(stroke_width));
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  canvas->DrawPath(path, paint);
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}  // namespace
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernamespace views {
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// static
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst char ProgressBar::kViewClassName[] = "ProgressBar";
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
136324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverProgressBar::ProgressBar()
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    : min_display_value_(0.0),
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      max_display_value_(1.0),
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      current_value_(0.0) {
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
142324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverProgressBar::~ProgressBar() {
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverdouble ProgressBar::GetNormalizedValue() const {
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  const double capped_value = std::min(
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      std::max(current_value_, min_display_value_), max_display_value_);
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  return (capped_value - min_display_value_) /
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      (max_display_value_ - min_display_value_);
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid ProgressBar::SetDisplayRange(double min_display_value,
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                  double max_display_value) {
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  if (min_display_value != min_display_value_ ||
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      max_display_value != max_display_value_) {
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    DCHECK(min_display_value < max_display_value);
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    min_display_value_ = min_display_value;
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    max_display_value_ = max_display_value;
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    SchedulePaint();
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  }
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid ProgressBar::SetValue(double value) {
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  if (value != current_value_) {
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    current_value_ = value;
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    SchedulePaint();
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  }
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid ProgressBar::SetTooltipText(const base::string16& tooltip_text) {
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  tooltip_text_ = tooltip_text;
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverbool ProgressBar::GetTooltipText(const gfx::Point& p,
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                 base::string16* tooltip) const {
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  DCHECK(tooltip);
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  *tooltip = tooltip_text_;
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  return !tooltip_text_.empty();
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid ProgressBar::GetAccessibleState(ui::AXViewState* state) {
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  state->role = ui::AX_ROLE_PROGRESS_INDICATOR;
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  state->AddStateFlag(ui::AX_STATE_READ_ONLY);
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvergfx::Size ProgressBar::GetPreferredSize() const {
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  gfx::Size pref_size(100, 11);
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  gfx::Insets insets = GetInsets();
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  pref_size.Enlarge(insets.width(), insets.height());
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  return pref_size;
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst char* ProgressBar::GetClassName() const {
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  return kViewClassName;
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid ProgressBar::OnPaint(gfx::Canvas* canvas) {
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  gfx::Rect content_bounds = GetContentsBounds();
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  int bar_left = content_bounds.x();
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  int bar_top = content_bounds.y();
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  int bar_width = content_bounds.width();
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  int bar_height = content_bounds.height();
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  const int progress_width =
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      static_cast<int>(bar_width * GetNormalizedValue() + 0.5);
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  // Draw background.
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  FillRoundRect(canvas,
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                bar_left, bar_top, bar_width, bar_height,
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                kCornerRadius,
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                kBackgroundColor, kBackgroundColor,
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                false);
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  StrokeRoundRect(canvas,
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  bar_left, bar_top,
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  bar_width, bar_height,
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  kCornerRadius,
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  kBackgroundBorderColor,
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  kBorderWidth);
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  if (progress_width > 1) {
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Draw inner if wide enough.
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if (progress_width > kBorderWidth * 2) {
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      canvas->Save();
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      SkPath inner_path;
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      AddRoundRectPathWithPadding(
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          bar_left, bar_top, progress_width, bar_height,
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          kCornerRadius,
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          0,
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          &inner_path);
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      canvas->ClipPath(inner_path, false);
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      const SkColor bar_colors[] = {
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        kBarTopColor,
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        kBarTopColor,
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        kBarColorStart,
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        kBarColorEnd,
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        kBarColorEnd,
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      };
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      // We want a thin 1-pixel line for kBarTopColor.
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      SkScalar scalar_height = SkIntToScalar(bar_height);
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      SkScalar highlight_width = SkScalarDiv(SK_Scalar1, scalar_height);
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      SkScalar border_width = SkScalarDiv(SkIntToScalar(kBorderWidth),
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                          scalar_height);
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      const SkScalar bar_points[] = {
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        0,
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        border_width,
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        border_width + highlight_width,
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        SK_Scalar1 - border_width,
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        SK_Scalar1,
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      };
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      const SkColor disabled_bar_colors[] = {
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        kDisabledBarColorStart,
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        kDisabledBarColorStart,
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        kDisabledBarColorEnd,
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        kDisabledBarColorEnd,
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      };
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      const SkScalar disabled_bar_points[] = {
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        0,
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        border_width,
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        SK_Scalar1 - border_width,
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        SK_Scalar1
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      };
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      // Do not start from (kBorderWidth, kBorderWidth) because it makes gaps
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      // between the inner and the border.
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      FillRoundRect(canvas,
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    bar_left, bar_top,
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    progress_width, bar_height,
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    kCornerRadius,
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    enabled() ? bar_colors : disabled_bar_colors,
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    enabled() ? bar_points : disabled_bar_points,
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    enabled() ? arraysize(bar_colors) :
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        arraysize(disabled_bar_colors),
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    false);
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      if (enabled()) {
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // Draw the highlight to the right.
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        const SkColor highlight_colors[] = {
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          SkColorSetA(kBarHighlightEnd, 0),
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          kBarHighlightEnd,
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          kBarHighlightEnd,
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        };
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        const SkScalar highlight_points[] = {
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          0,
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          SK_Scalar1 - SkScalarDiv(SkIntToScalar(kBorderWidth), scalar_height),
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          SK_Scalar1,
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        };
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        SkPaint paint;
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        paint.setStyle(SkPaint::kFill_Style);
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        paint.setFlags(SkPaint::kAntiAlias_Flag);
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        SkPoint p[2];
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        int highlight_left =
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            std::max(0, progress_width - kHighlightWidth - kBorderWidth);
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        p[0].iset(highlight_left, 0);
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        p[1].iset(progress_width, 0);
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        skia::RefPtr<SkShader> s =
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            skia::AdoptRef(SkGradientShader::CreateLinear(
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                p, highlight_colors, highlight_points,
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                arraysize(highlight_colors), SkShader::kClamp_TileMode));
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        paint.setShader(s.get());
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        canvas->DrawRect(gfx::Rect(highlight_left, 0,
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                   kHighlightWidth + kBorderWidth, bar_height),
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                         paint);
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      }
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      canvas->Restore();
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Draw bar stroke
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    StrokeRoundRect(canvas,
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    bar_left, bar_top, progress_width, bar_height,
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    kCornerRadius,
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    enabled() ? kBarBorderColor : kDisabledBarBorderColor,
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    kBorderWidth);
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  }
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}  // namespace views
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver