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