blob: 8a506f44a1749a83aebb7636171473a3adc4a83a [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#include "SkWidget.h"
9#include "SkCanvas.h"
10#include "SkShader.h"
11#include "SkInterpolator.h"
12#include "SkTime.h"
13
14SkProgressView::SkProgressView(uint32_t flags) : SkView(flags), fOnShader(NULL), fOffShader(NULL)
15{
16 fValue = 0;
17 fMax = 0;
18 fInterp = NULL;
19 fDoInterp = false;
20}
21
22SkProgressView::~SkProgressView()
23{
24 delete fInterp;
mike@reedtribe.org2f834592011-03-18 10:33:47 +000025 SkSafeUnref(fOnShader);
26 SkSafeUnref(fOffShader);
reed@android.com8a1c16f2008-12-17 15:59:43 +000027}
28
29void SkProgressView::setMax(U16CPU max)
30{
31 if (fMax != max)
32 {
33 fMax = SkToU16(max);
34 if (fValue > 0)
35 this->inval(NULL);
36 }
37}
38
39void SkProgressView::setValue(U16CPU value)
40{
41 if (fValue != value)
42 {
43 if (fDoInterp)
44 {
45 if (fInterp)
46 delete fInterp;
47 fInterp = new SkInterpolator(1, 2);
48 SkScalar x = (SkScalar)(fValue << 8);
49 fInterp->setKeyFrame(0, SkTime::GetMSecs(), &x, 0);
50 x = (SkScalar)(value << 8);
51 fInterp->setKeyFrame(1, SkTime::GetMSecs() + 333, &x);
52 }
53 fValue = SkToU16(value);
54 this->inval(NULL);
55 }
56}
57
58void SkProgressView::onDraw(SkCanvas* canvas)
59{
60 if (fMax == 0)
61 return;
62
63 SkFixed percent;
64
65 if (fInterp)
66 {
67 SkScalar x;
68 if (fInterp->timeToValues(SkTime::GetMSecs(), &x) == SkInterpolator::kFreezeEnd_Result)
69 {
70 delete fInterp;
71 fInterp = NULL;
72 }
73 percent = (SkFixed)x; // now its 16.8
74 percent = SkMax32(0, SkMin32(percent, fMax << 8)); // now its pinned
75 percent = SkFixedDiv(percent, fMax << 8); // now its 0.16
76 this->inval(NULL);
77 }
78 else
79 {
80 U16CPU value = SkMax32(0, SkMin32(fValue, fMax));
81 percent = SkFixedDiv(value, fMax);
82 }
83
84
85 SkRect r;
86 SkPaint p;
87
88 r.set(0, 0, this->width(), this->height());
89 p.setAntiAlias(true);
90
91 r.fRight = r.fLeft + SkScalarMul(r.width(), SkFixedToScalar(percent));
92 p.setStyle(SkPaint::kFill_Style);
93
94 p.setColor(SK_ColorDKGRAY);
95 p.setShader(fOnShader);
96 canvas->drawRect(r, p);
97
98 p.setColor(SK_ColorWHITE);
99 p.setShader(fOffShader);
100 r.fLeft = r.fRight;
101 r.fRight = this->width() - SK_Scalar1;
102 if (r.width() > 0)
103 canvas->drawRect(r, p);
104}
105
106#include "SkImageDecoder.h"
107
108static SkShader* inflate_shader(const char file[])
109{
110 SkBitmap bm;
111
112 return SkImageDecoder::DecodeFile(file, &bm) ?
113 SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode) :
114 NULL;
115}
116
117void SkProgressView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
118{
119 this->INHERITED::onInflate(dom, node);
120
121 const char* s;
122
123 SkASSERT(fOnShader == NULL);
124 SkASSERT(fOffShader == NULL);
125
126 if ((s = dom.findAttr(node, "src-on")) != NULL)
127 fOnShader = inflate_shader(s);
128 if ((s = dom.findAttr(node, "src-off")) != NULL)
129 fOffShader = inflate_shader(s);
130 (void)dom.findBool(node, "do-interp", &fDoInterp);
131}
132