1#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	SkSafeUnref(fOnShader);
19	SkSafeUnref(fOffShader);
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
126