| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "views/controls/progress_bar.h" | 5 #include "views/controls/progress_bar.h" |
| 6 | 6 |
| 7 #include <algorithm> |
| 7 #include <string> | 8 #include <string> |
| 8 | 9 |
| 9 #include "base/logging.h" | 10 #include "base/logging.h" |
| 10 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 11 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
| 12 #include "third_party/skia/include/effects/SkBlurMaskFilter.h" | 13 #include "third_party/skia/include/effects/SkBlurMaskFilter.h" |
| 13 #include "third_party/skia/include/effects/SkGradientShader.h" | 14 #include "third_party/skia/include/effects/SkGradientShader.h" |
| 14 #include "ui/base/accessibility/accessible_view_state.h" | 15 #include "ui/base/accessibility/accessible_view_state.h" |
| 15 #include "ui/gfx/canvas_skia.h" | 16 #include "ui/gfx/canvas_skia.h" |
| 16 #include "ui/gfx/color_utils.h" | 17 #include "ui/gfx/color_utils.h" |
| 17 #include "ui/gfx/font.h" | 18 #include "ui/gfx/font.h" |
| 18 #include "ui/gfx/insets.h" | 19 #include "ui/gfx/insets.h" |
| 19 #include "views/background.h" | 20 #include "views/background.h" |
| 20 #include "views/border.h" | 21 #include "views/border.h" |
| 21 #include "views/painter.h" | 22 #include "views/painter.h" |
| 22 | 23 |
| 24 using std::max; |
| 25 using std::min; |
| 26 |
| 23 namespace { | 27 namespace { |
| 24 | 28 |
| 25 // Corner radius for the progress bar's border. | 29 // Corner radius for the progress bar's border. |
| 26 const int kCornerRadius = 3; | 30 const int kCornerRadius = 3; |
| 27 | 31 |
| 28 // Progress bar's border width | 32 // Progress bar's border width |
| 29 const int kBorderWidth = 1; | 33 const int kBorderWidth = 1; |
| 30 | 34 |
| 31 static void AddRoundRectPathWithPadding(int x, int y, | 35 void AddRoundRectPathWithPadding(int x, int y, |
| 32 int w, int h, | 36 int w, int h, |
| 33 int corner_radius, | 37 int corner_radius, |
| 34 SkScalar padding, | 38 SkScalar padding, |
| 35 SkPath* path) { | 39 SkPath* path) { |
| 36 DCHECK(path); | 40 DCHECK(path); |
| 37 if (path == NULL) | 41 if (path == NULL) |
| 38 return; | 42 return; |
| 39 SkRect rect; | 43 SkRect rect; |
| 40 rect.set( | 44 rect.set( |
| 41 SkIntToScalar(x) + padding, SkIntToScalar(y) + padding, | 45 SkIntToScalar(x) + padding, SkIntToScalar(y) + padding, |
| 42 SkIntToScalar(x + w) - padding, SkIntToScalar(y + h) - padding); | 46 SkIntToScalar(x + w) - padding, SkIntToScalar(y + h) - padding); |
| 43 path->addRoundRect( | 47 path->addRoundRect( |
| 44 rect, | 48 rect, |
| 45 SkIntToScalar(corner_radius) - padding, | 49 SkIntToScalar(corner_radius) - padding, |
| 46 SkIntToScalar(corner_radius) - padding); | 50 SkIntToScalar(corner_radius) - padding); |
| 47 } | 51 } |
| 48 | 52 |
| 49 static void AddRoundRectPath(int x, int y, | 53 void AddRoundRectPath(int x, int y, |
| 50 int w, int h, | 54 int w, int h, |
| 51 int corner_radius, | 55 int corner_radius, |
| 52 SkPath* path) { | 56 SkPath* path) { |
| 53 static const SkScalar half = SkIntToScalar(1) / 2; | 57 static const SkScalar half = SkIntToScalar(1) / 2; |
| 54 AddRoundRectPathWithPadding(x, y, w, h, corner_radius, half, path); | 58 AddRoundRectPathWithPadding(x, y, w, h, corner_radius, half, path); |
| 55 } | 59 } |
| 56 | 60 |
| 57 static void FillRoundRect(gfx::Canvas* canvas, | 61 void FillRoundRect(gfx::Canvas* canvas, |
| 58 int x, int y, | 62 int x, int y, |
| 59 int w, int h, | 63 int w, int h, |
| 60 int corner_radius, | 64 int corner_radius, |
| 61 const SkColor colors[], | 65 const SkColor colors[], |
| 62 const SkScalar points[], | 66 const SkScalar points[], |
| 63 int count, | 67 int count, |
| 64 bool gradient_horizontal) { | 68 bool gradient_horizontal) { |
| 65 SkPath path; | 69 SkPath path; |
| 66 AddRoundRectPath(x, y, w, h, corner_radius, &path); | 70 AddRoundRectPath(x, y, w, h, corner_radius, &path); |
| 67 SkPaint paint; | 71 SkPaint paint; |
| 68 paint.setStyle(SkPaint::kFill_Style); | 72 paint.setStyle(SkPaint::kFill_Style); |
| 69 paint.setFlags(SkPaint::kAntiAlias_Flag); | 73 paint.setFlags(SkPaint::kAntiAlias_Flag); |
| 70 | 74 |
| 71 SkPoint p[2]; | 75 SkPoint p[2]; |
| 72 p[0].set(SkIntToScalar(x), SkIntToScalar(y)); | 76 p[0].set(SkIntToScalar(x), SkIntToScalar(y)); |
| 73 if (gradient_horizontal) { | 77 if (gradient_horizontal) { |
| 74 p[1].set(SkIntToScalar(x + w), SkIntToScalar(y)); | 78 p[1].set(SkIntToScalar(x + w), SkIntToScalar(y)); |
| 75 } else { | 79 } else { |
| 76 p[1].set(SkIntToScalar(x), SkIntToScalar(y + h)); | 80 p[1].set(SkIntToScalar(x), SkIntToScalar(y + h)); |
| 77 } | 81 } |
| 78 SkShader* s = SkGradientShader::CreateLinear( | 82 SkShader* s = SkGradientShader::CreateLinear( |
| 79 p, colors, points, count, SkShader::kClamp_TileMode, NULL); | 83 p, colors, points, count, SkShader::kClamp_TileMode, NULL); |
| 80 paint.setShader(s); | 84 paint.setShader(s); |
| 81 // Need to unref shader, otherwise never deleted. | 85 // Need to unref shader, otherwise never deleted. |
| 82 s->unref(); | 86 s->unref(); |
| 83 | 87 |
| 84 canvas->AsCanvasSkia()->drawPath(path, paint); | 88 canvas->AsCanvasSkia()->drawPath(path, paint); |
| 85 } | 89 } |
| 86 | 90 |
| 87 static void FillRoundRect(gfx::Canvas* canvas, | 91 void FillRoundRect(gfx::Canvas* canvas, |
| 88 int x, int y, | 92 int x, int y, |
| 89 int w, int h, | 93 int w, int h, |
| 90 int corner_radius, | 94 int corner_radius, |
| 91 SkColor gradient_start_color, | 95 SkColor gradient_start_color, |
| 92 SkColor gradient_end_color, | 96 SkColor gradient_end_color, |
| 93 bool gradient_horizontal) { | 97 bool gradient_horizontal) { |
| 94 if (gradient_start_color != gradient_end_color) { | 98 if (gradient_start_color != gradient_end_color) { |
| 95 SkColor colors[2] = { gradient_start_color, gradient_end_color }; | 99 SkColor colors[2] = { gradient_start_color, gradient_end_color }; |
| 96 FillRoundRect(canvas, x, y, w, h, corner_radius, | 100 FillRoundRect(canvas, x, y, w, h, corner_radius, |
| 97 colors, NULL, 2, gradient_horizontal); | 101 colors, NULL, 2, gradient_horizontal); |
| 98 } else { | 102 } else { |
| 99 SkPath path; | 103 SkPath path; |
| 100 AddRoundRectPath(x, y, w, h, corner_radius, &path); | 104 AddRoundRectPath(x, y, w, h, corner_radius, &path); |
| 101 SkPaint paint; | 105 SkPaint paint; |
| 102 paint.setStyle(SkPaint::kFill_Style); | 106 paint.setStyle(SkPaint::kFill_Style); |
| 103 paint.setFlags(SkPaint::kAntiAlias_Flag); | 107 paint.setFlags(SkPaint::kAntiAlias_Flag); |
| 104 paint.setColor(gradient_start_color); | 108 paint.setColor(gradient_start_color); |
| 105 canvas->AsCanvasSkia()->drawPath(path, paint); | 109 canvas->AsCanvasSkia()->drawPath(path, paint); |
| 106 } | 110 } |
| 107 } | 111 } |
| 108 | 112 |
| 109 static void StrokeRoundRect(gfx::Canvas* canvas, | 113 void StrokeRoundRect(gfx::Canvas* canvas, |
| 110 int x, int y, | 114 int x, int y, |
| 111 int w, int h, | 115 int w, int h, |
| 112 int corner_radius, | 116 int corner_radius, |
| 113 SkColor stroke_color, | 117 SkColor stroke_color, |
| 114 int stroke_width) { | 118 int stroke_width) { |
| 115 SkPath path; | 119 SkPath path; |
| 116 AddRoundRectPath(x, y, w, h, corner_radius, &path); | 120 AddRoundRectPath(x, y, w, h, corner_radius, &path); |
| 117 SkPaint paint; | 121 SkPaint paint; |
| 118 paint.setShader(NULL); | 122 paint.setShader(NULL); |
| 119 paint.setColor(stroke_color); | 123 paint.setColor(stroke_color); |
| 120 paint.setStyle(SkPaint::kStroke_Style); | 124 paint.setStyle(SkPaint::kStroke_Style); |
| 121 paint.setFlags(SkPaint::kAntiAlias_Flag); | 125 paint.setFlags(SkPaint::kAntiAlias_Flag); |
| 122 paint.setStrokeWidth(SkIntToScalar(stroke_width)); | 126 paint.setStrokeWidth(SkIntToScalar(stroke_width)); |
| 123 canvas->AsCanvasSkia()->drawPath(path, paint); | 127 canvas->AsCanvasSkia()->drawPath(path, paint); |
| 124 } | 128 } |
| 125 | 129 |
| 126 } // anonymous namespace | 130 } // anonymous namespace |
| 127 | 131 |
| 128 namespace views { | 132 namespace views { |
| 129 | 133 |
| 130 // static | 134 // static |
| 131 const char ProgressBar::kViewClassName[] = "views/ProgressBar"; | 135 const char ProgressBar::kViewClassName[] = "views/ProgressBar"; |
| 132 // static: progress bar's maximum value. | |
| 133 const int ProgressBar::kMaxProgress = 100; | |
| 134 | 136 |
| 135 | 137 ProgressBar::ProgressBar() |
| 136 ProgressBar::ProgressBar(): progress_(0) { | 138 : min_display_value_(0.0), |
| 139 max_display_value_(1.0), |
| 140 current_value_(0.0) { |
| 137 } | 141 } |
| 138 | 142 |
| 139 ProgressBar::~ProgressBar() { | 143 ProgressBar::~ProgressBar() { |
| 140 } | 144 } |
| 141 | 145 |
| 142 gfx::Size ProgressBar::GetPreferredSize() { | 146 gfx::Size ProgressBar::GetPreferredSize() { |
| 143 return gfx::Size(100, 16); | 147 return gfx::Size(100, 16); |
| 144 } | 148 } |
| 145 | 149 |
| 150 std::string ProgressBar::GetClassName() const { |
| 151 return kViewClassName; |
| 152 } |
| 153 |
| 154 void ProgressBar::GetAccessibleState(ui::AccessibleViewState* state) { |
| 155 state->role = ui::AccessibilityTypes::ROLE_PROGRESSBAR; |
| 156 state->state = ui::AccessibilityTypes::STATE_READONLY; |
| 157 } |
| 158 |
| 146 void ProgressBar::OnPaint(gfx::Canvas* canvas) { | 159 void ProgressBar::OnPaint(gfx::Canvas* canvas) { |
| 160 const double capped_value = |
| 161 min(max(current_value_, min_display_value_), max_display_value_); |
| 162 const double capped_fraction = |
| 163 (capped_value - min_display_value_) / |
| 164 (max_display_value_ - min_display_value_); |
| 165 const int progress_width = static_cast<int>(width() * capped_fraction + 0.5); |
| 166 |
| 147 #if defined(OS_CHROMEOS) | 167 #if defined(OS_CHROMEOS) |
| 148 const SkColor background_colors[] = { | 168 const SkColor background_colors[] = { |
| 149 SkColorSetRGB(0xBB, 0xBB, 0xBB), | 169 SkColorSetRGB(0xBB, 0xBB, 0xBB), |
| 150 SkColorSetRGB(0xE7, 0xE7, 0xE7), | 170 SkColorSetRGB(0xE7, 0xE7, 0xE7), |
| 151 SkColorSetRGB(0xFE, 0xFE, 0xFE) | 171 SkColorSetRGB(0xFE, 0xFE, 0xFE) |
| 152 }; | 172 }; |
| 153 | 173 |
| 154 const SkScalar background_points[] = { | 174 const SkScalar background_points[] = { |
| 155 SkDoubleToScalar(0), | 175 SkDoubleToScalar(0), |
| 156 SkDoubleToScalar(0.1), | 176 SkDoubleToScalar(0.1), |
| 157 SkDoubleToScalar(1) | 177 SkDoubleToScalar(1) |
| 158 }; | 178 }; |
| 159 const SkColor background_border_color = SkColorSetRGB(0xA1, 0xA1, 0xA1); | 179 const SkColor background_border_color = SkColorSetRGB(0xA1, 0xA1, 0xA1); |
| 160 | 180 |
| 161 // Draw background. | 181 // Draw background. |
| 162 FillRoundRect(canvas, | 182 FillRoundRect(canvas, |
| 163 0, 0, width(), height(), | 183 0, 0, width(), height(), |
| 164 kCornerRadius, | 184 kCornerRadius, |
| 165 background_colors, | 185 background_colors, |
| 166 background_points, | 186 background_points, |
| 167 arraysize(background_colors), | 187 arraysize(background_colors), |
| 168 false); | 188 false); |
| 169 StrokeRoundRect(canvas, | 189 StrokeRoundRect(canvas, |
| 170 0, 0, | 190 0, 0, |
| 171 width(), height(), | 191 width(), height(), |
| 172 kCornerRadius, | 192 kCornerRadius, |
| 173 background_border_color, | 193 background_border_color, |
| 174 kBorderWidth); | 194 kBorderWidth); |
| 175 | 195 |
| 176 if (progress_ * width() > 1) { | 196 if (progress_width > 1) { |
| 177 int progress_width = progress_ * width() / kMaxProgress; | 197 const bool enabled = IsEnabled(); |
| 178 | |
| 179 bool enabled = IsEnabled(); | |
| 180 | 198 |
| 181 const SkColor bar_color_start = enabled ? | 199 const SkColor bar_color_start = enabled ? |
| 182 SkColorSetRGB(100, 116, 147) : | 200 SkColorSetRGB(100, 116, 147) : |
| 183 SkColorSetRGB(229, 232, 237); | 201 SkColorSetRGB(229, 232, 237); |
| 184 const SkColor bar_color_end = enabled ? | 202 const SkColor bar_color_end = enabled ? |
| 185 SkColorSetRGB(65, 73, 87) : | 203 SkColorSetRGB(65, 73, 87) : |
| 186 SkColorSetRGB(224, 225, 227); | 204 SkColorSetRGB(224, 225, 227); |
| 187 | 205 |
| 188 const SkColor bar_outer_color = enabled ? | 206 const SkColor bar_outer_color = enabled ? |
| 189 SkColorSetRGB(0x4A, 0x4A, 0x4A) : | 207 SkColorSetRGB(0x4A, 0x4A, 0x4A) : |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 SkColor background_color_start = SkColorSetRGB(212, 212, 212); | 264 SkColor background_color_start = SkColorSetRGB(212, 212, 212); |
| 247 SkColor background_color_end = SkColorSetRGB(252, 252, 252); | 265 SkColor background_color_end = SkColorSetRGB(252, 252, 252); |
| 248 SkColor border_color = SkColorSetRGB(144, 144, 144); | 266 SkColor border_color = SkColorSetRGB(144, 144, 144); |
| 249 | 267 |
| 250 FillRoundRect(canvas, | 268 FillRoundRect(canvas, |
| 251 0, 0, width(), height(), | 269 0, 0, width(), height(), |
| 252 kCornerRadius, | 270 kCornerRadius, |
| 253 background_color_start, | 271 background_color_start, |
| 254 background_color_end, | 272 background_color_end, |
| 255 false); | 273 false); |
| 256 if (progress_ * width() > 1) { | 274 if (progress_width > 1) { |
| 257 FillRoundRect(canvas, | 275 FillRoundRect(canvas, |
| 258 0, 0, | 276 0, 0, |
| 259 progress_ * width() / kMaxProgress, height(), | 277 progress_width, height(), |
| 260 kCornerRadius, | 278 kCornerRadius, |
| 261 bar_color_start, | 279 bar_color_start, |
| 262 bar_color_end, | 280 bar_color_end, |
| 263 false); | 281 false); |
| 264 } | 282 } |
| 265 StrokeRoundRect(canvas, | 283 StrokeRoundRect(canvas, |
| 266 0, 0, | 284 0, 0, |
| 267 width(), height(), | 285 width(), height(), |
| 268 kCornerRadius, | 286 kCornerRadius, |
| 269 border_color, | 287 border_color, |
| 270 kBorderWidth); | 288 kBorderWidth); |
| 271 #endif | 289 #endif |
| 272 } | 290 } |
| 273 | 291 |
| 274 std::string ProgressBar::GetClassName() const { | |
| 275 return kViewClassName; | |
| 276 } | |
| 277 | |
| 278 void ProgressBar::SetProgress(int progress) { | |
| 279 progress_ = progress; | |
| 280 if (progress_ < 0) | |
| 281 progress_ = 0; | |
| 282 else if (progress_ > kMaxProgress) | |
| 283 progress_ = kMaxProgress; | |
| 284 SchedulePaint(); | |
| 285 } | |
| 286 | |
| 287 int ProgressBar::GetProgress() const { | |
| 288 return progress_; | |
| 289 } | |
| 290 | |
| 291 void ProgressBar::AddProgress(int tick) { | |
| 292 SetProgress(progress_ + tick); | |
| 293 } | |
| 294 | |
| 295 void ProgressBar::SetTooltipText(const std::wstring& tooltip_text) { | |
| 296 tooltip_text_ = WideToUTF16Hack(tooltip_text); | |
| 297 } | |
| 298 | |
| 299 bool ProgressBar::GetTooltipText(const gfx::Point& p, std::wstring* tooltip) { | 292 bool ProgressBar::GetTooltipText(const gfx::Point& p, std::wstring* tooltip) { |
| 300 DCHECK(tooltip); | 293 DCHECK(tooltip); |
| 301 if (tooltip == NULL) | 294 if (tooltip == NULL) |
| 302 return false; | 295 return false; |
| 303 tooltip->assign(UTF16ToWideHack(tooltip_text_)); | 296 tooltip->assign(UTF16ToWideHack(tooltip_text_)); |
| 304 return !tooltip_text_.empty(); | 297 return !tooltip_text_.empty(); |
| 305 } | 298 } |
| 306 | 299 |
| 307 void ProgressBar::OnEnabledChanged() { | 300 void ProgressBar::SetDisplayRange(double min_display_value, |
| 308 View::OnEnabledChanged(); | 301 double max_display_value) { |
| 309 // TODO(denisromanov): Need to switch progress bar color here? | 302 if (min_display_value != min_display_value_ || |
| 303 max_display_value != max_display_value_) { |
| 304 DCHECK(min_display_value < max_display_value); |
| 305 min_display_value_ = min_display_value; |
| 306 max_display_value_ = max_display_value; |
| 307 SchedulePaint(); |
| 308 } |
| 310 } | 309 } |
| 311 | 310 |
| 312 void ProgressBar::GetAccessibleState(ui::AccessibleViewState* state) { | 311 void ProgressBar::SetValue(double value) { |
| 313 state->role = ui::AccessibilityTypes::ROLE_PROGRESSBAR; | 312 if (value != current_value_) { |
| 314 state->state = ui::AccessibilityTypes::STATE_READONLY; | 313 current_value_ = value; |
| 314 SchedulePaint(); |
| 315 } |
| 316 } |
| 317 |
| 318 void ProgressBar::SetTooltipText(const std::wstring& tooltip_text) { |
| 319 tooltip_text_ = WideToUTF16Hack(tooltip_text); |
| 315 } | 320 } |
| 316 | 321 |
| 317 } // namespace views | 322 } // namespace views |
| OLD | NEW |