 Chromium Code Reviews
 Chromium Code Reviews Issue 1236463002:
  Vectorize download shelf progress indicators  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 1236463002:
  Vectorize download shelf progress indicators  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| Index: chrome/browser/download/download_shelf.cc | 
| diff --git a/chrome/browser/download/download_shelf.cc b/chrome/browser/download/download_shelf.cc | 
| index d120fe2e3270e5a7051eb5def0e01589e0060ef3..ae8e37d70397bd3a486694d8c1aecc9eb4fb260e 100644 | 
| --- a/chrome/browser/download/download_shelf.cc | 
| +++ b/chrome/browser/download/download_shelf.cc | 
| @@ -14,6 +14,7 @@ | 
| #include "base/single_thread_task_runner.h" | 
| #include "base/strings/string_number_conversions.h" | 
| #include "base/thread_task_runner_handle.h" | 
| +#include "base/time/time.h" | 
| #include "chrome/browser/download/download_item_model.h" | 
| #include "chrome/browser/download/download_service.h" | 
| #include "chrome/browser/download/download_service_factory.h" | 
| @@ -28,11 +29,12 @@ | 
| #include "content/public/browser/download_manager.h" | 
| #include "content/public/browser/web_contents.h" | 
| #include "grit/theme_resources.h" | 
| +#include "third_party/skia/include/core/SkPaint.h" | 
| +#include "third_party/skia/include/core/SkPath.h" | 
| #include "ui/base/l10n/l10n_util.h" | 
| #include "ui/base/resource/resource_bundle.h" | 
| #include "ui/gfx/animation/animation.h" | 
| #include "ui/gfx/canvas.h" | 
| -#include "ui/gfx/image/image_skia.h" | 
| using content::DownloadItem; | 
| @@ -66,115 +68,63 @@ DownloadShelf::~DownloadShelf() {} | 
| // Download progress painting -------------------------------------------------- | 
| -// Common images used for download progress animations. We load them once the | 
| -// first time we do a progress paint, then reuse them as they are always the | 
| -// same. | 
| -gfx::ImageSkia* g_foreground_16 = NULL; | 
| -gfx::ImageSkia* g_background_16 = NULL; | 
| - | 
| // static | 
| void DownloadShelf::PaintDownloadProgress( | 
| gfx::Canvas* canvas, | 
| - const BoundsAdjusterCallback& rtl_mirror, | 
| - int origin_x, | 
| - int origin_y, | 
| - int start_angle, | 
| + const base::TimeTicks& progress_start_time, | 
| int percent_done) { | 
| - // Load up our common images. | 
| - if (!g_background_16) { | 
| - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 
| - g_foreground_16 = rb.GetImageSkiaNamed(IDR_DOWNLOAD_PROGRESS_FOREGROUND_16); | 
| - g_background_16 = rb.GetImageSkiaNamed(IDR_DOWNLOAD_PROGRESS_BACKGROUND_16); | 
| - DCHECK_EQ(g_foreground_16->width(), g_background_16->width()); | 
| - DCHECK_EQ(g_foreground_16->height(), g_background_16->height()); | 
| - } | 
| - | 
| - // We start by storing the bounds of the images so that it is easy to mirror | 
| - // the bounds if the UI layout is RTL. | 
| - gfx::Rect bounds(origin_x, origin_y, g_background_16->width(), | 
| - g_background_16->height()); | 
| - | 
| - // Mirror the positions if necessary. | 
| - rtl_mirror.Run(&bounds); | 
| - | 
| - // Draw the background progress image. | 
| - canvas->DrawImageInt(*g_background_16, bounds.x(), bounds.y()); | 
| - | 
| - // Layer the foreground progress image in an arc proportional to the download | 
| - // progress. The arc grows clockwise, starting in the midnight position, as | 
| - // the download progresses. However, if the download does not have known total | 
| - // size (the server didn't give us one), then we just spin an arc around until | 
| - // we're done. | 
| - float sweep_angle = 0.0; | 
| - float start_pos = static_cast<float>(kStartAngleDegrees); | 
| + // Draw background (light blue circle). | 
| + SkPaint bg_paint; | 
| + bg_paint.setStyle(SkPaint::kFill_Style); | 
| + bg_paint.setColor(SkColorSetRGB(0xD7, 0xE4, 0xFA)); | 
| 
Peter Kasting
2015/07/10 23:53:34
Any way to use an existing theme color, or compute
 
Evan Stade
2015/07/11 00:18:34
This CL certainly makes it easier to theme this co
 
Peter Kasting
2015/07/11 07:03:25
I think our goal should be to Do It Right, which m
 
Evan Stade
2015/07/13 23:25:04
The overall goal is to do it right. The goal of ea
 
Peter Kasting
2015/07/14 01:25:22
That's fine, if we had a concrete plan for how we
 
Evan Stade
2015/07/14 01:52:18
You're right, I am not promising to fix it right a
 
Peter Kasting
2015/07/14 18:44:33
Done.
 | 
| + bg_paint.setAntiAlias(true); | 
| + SkPath bg; | 
| + bg.addCircle(20, 20, 13); | 
| 
Peter Kasting
2015/07/10 23:53:34
Can we compute this value, the progress arc values
 
Evan Stade
2015/07/11 00:18:35
I don't know how we would do that. We could do som
 
Peter Kasting
2015/07/11 07:03:25
Well, kSMallProgressIconSize wasn't implicit in th
 
Evan Stade
2015/07/13 23:25:04
Yes, it was the width/height of the png.
 
Peter Kasting
2015/07/14 01:25:22
It seems like this is related to the (20, 20) posi
 | 
| + canvas->DrawPath(bg, bg_paint); | 
| + | 
| + // Calculate progress. | 
| + SkScalar sweep_angle = 0.f; | 
| + // Start at 12 o'clock. | 
| + SkScalar start_pos = SkIntToScalar(270); | 
| if (percent_done < 0) { | 
| - sweep_angle = kUnknownAngleDegrees; | 
| - start_pos = static_cast<float>(start_angle); | 
| + // For unknown size downloads, draw a 50 degree sweep that moves at | 
| + // 0.08 degrees per millisecond. | 
| + sweep_angle = 50.f; | 
| + start_pos += static_cast<SkScalar>( | 
| + (base::TimeTicks::Now() - progress_start_time).InMilliseconds() * 0.08); | 
| } else if (percent_done > 0) { | 
| - sweep_angle = static_cast<float>(kMaxDegrees / 100.0 * percent_done); | 
| + sweep_angle = static_cast<SkScalar>(360 * percent_done / 100.0); | 
| } | 
| - // Set up an arc clipping region for the foreground image. Don't bother using | 
| - // a clipping region if it would round to 360 (really 0) degrees, since that | 
| - // would eliminate the foreground completely and be quite confusing (it would | 
| - // look like 0% complete when it should be almost 100%). | 
| - canvas->Save(); | 
| - if (sweep_angle < static_cast<float>(kMaxDegrees - 1)) { | 
| - SkRect oval; | 
| - oval.set(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y()), | 
| - SkIntToScalar(bounds.x() + DownloadShelf::kSmallProgressIconSize), | 
| - SkIntToScalar(bounds.y() + DownloadShelf::kSmallProgressIconSize)); | 
| - SkPath path; | 
| - path.arcTo(oval, | 
| - SkFloatToScalar(start_pos), | 
| - SkFloatToScalar(sweep_angle), false); | 
| - path.lineTo( | 
| - SkIntToScalar(bounds.x() + DownloadShelf::kSmallProgressIconSize / 2), | 
| - SkIntToScalar(bounds.y() + DownloadShelf::kSmallProgressIconSize / 2)); | 
| - | 
| - // gfx::Canvas::ClipPath does not provide for anti-aliasing. | 
| - canvas->sk_canvas()->clipPath(path, SkRegion::kIntersect_Op, true); | 
| - } | 
| - | 
| - canvas->DrawImageInt(*g_foreground_16, bounds.x(), bounds.y()); | 
| - canvas->Restore(); | 
| + // Draw progress. | 
| + SkPath progress; | 
| + progress.addArc(SkRect::MakeXYWH(7, 7, 25, 25), start_pos, sweep_angle); | 
| + SkPaint progress_paint; | 
| + progress_paint.setColor(SkColorSetRGB(0x41, 0x84, 0xF4)); | 
| + progress_paint.setStyle(SkPaint::kStroke_Style); | 
| + progress_paint.setStrokeWidth(1.7); | 
| + progress_paint.setAntiAlias(true); | 
| + canvas->DrawPath(progress, progress_paint); | 
| } | 
| // static | 
| void DownloadShelf::PaintDownloadComplete( | 
| gfx::Canvas* canvas, | 
| - const BoundsAdjusterCallback& rtl_mirror, | 
| - int origin_x, | 
| - int origin_y, | 
| double animation_progress) { | 
| - // Load up our common images. | 
| - if (!g_foreground_16) { | 
| - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 
| - g_foreground_16 = rb.GetImageSkiaNamed(IDR_DOWNLOAD_PROGRESS_FOREGROUND_16); | 
| - } | 
| - | 
| - gfx::Rect complete_bounds(origin_x, origin_y, g_foreground_16->width(), | 
| - g_foreground_16->height()); | 
| - // Mirror the positions if necessary. | 
| - rtl_mirror.Run(&complete_bounds); | 
| - | 
| // Start at full opacity, then loop back and forth five times before ending | 
| // at zero opacity. | 
| - canvas->DrawImageInt(*g_foreground_16, complete_bounds.x(), | 
| - complete_bounds.y(), GetOpacity(animation_progress)); | 
| + canvas->sk_canvas()->saveLayerAlpha(nullptr, GetOpacity(animation_progress)); | 
| + PaintDownloadProgress(canvas, base::TimeTicks(), 100); | 
| + canvas->sk_canvas()->restore(); | 
| } | 
| // static | 
| void DownloadShelf::PaintDownloadInterrupted( | 
| gfx::Canvas* canvas, | 
| - const BoundsAdjusterCallback& rtl_mirror, | 
| - int origin_x, | 
| - int origin_y, | 
| double animation_progress) { | 
| // Start at zero opacity, then loop back and forth five times before ending | 
| // at full opacity. | 
| - PaintDownloadComplete(canvas, rtl_mirror, origin_x, origin_y, | 
| - 1.0 - animation_progress); | 
| + PaintDownloadComplete(canvas, 1.0 - animation_progress); | 
| } | 
| void DownloadShelf::AddDownload(DownloadItem* download) { |