aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/views/SkProgressView.cpp
blob: a34c28436148f4a96ba75990f6bb922ffea68a76 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "SkWidget.h"
#include "SkCanvas.h"
#include "SkShader.h"
#include "SkInterpolator.h"
#include "SkTime.h"

SkProgressView::SkProgressView(uint32_t flags) : SkView(flags), fOnShader(NULL), fOffShader(NULL)
{
	fValue = 0;
	fMax = 0;
	fInterp = NULL;
	fDoInterp = false;
}

SkProgressView::~SkProgressView()
{
	delete fInterp;
	fOnShader->safeUnref();
	fOffShader->safeUnref();
}

void SkProgressView::setMax(U16CPU max)
{
	if (fMax != max)
	{
		fMax = SkToU16(max);
		if (fValue > 0)
			this->inval(NULL);
	}
}

void SkProgressView::setValue(U16CPU value)
{
	if (fValue != value)
	{
		if (fDoInterp)
		{
			if (fInterp)
				delete fInterp;
			fInterp = new SkInterpolator(1, 2);
			SkScalar x = (SkScalar)(fValue << 8);
			fInterp->setKeyFrame(0, SkTime::GetMSecs(), &x, 0);
			x = (SkScalar)(value << 8);
			fInterp->setKeyFrame(1, SkTime::GetMSecs() + 333, &x);
		}
		fValue = SkToU16(value);
		this->inval(NULL);
	}
}

void SkProgressView::onDraw(SkCanvas* canvas)
{
	if (fMax == 0)
		return;

	SkFixed	percent;

	if (fInterp)
	{
		SkScalar x;
		if (fInterp->timeToValues(SkTime::GetMSecs(), &x) == SkInterpolator::kFreezeEnd_Result)
		{
			delete fInterp;
			fInterp = NULL;
		}
		percent = (SkFixed)x;	// now its 16.8
		percent = SkMax32(0, SkMin32(percent, fMax << 8));	// now its pinned
		percent = SkFixedDiv(percent, fMax << 8);	// now its 0.16
		this->inval(NULL);
	}
	else
	{
		U16CPU value = SkMax32(0, SkMin32(fValue, fMax));
		percent = SkFixedDiv(value, fMax);
	}


	SkRect	r;
	SkPaint	p;

	r.set(0, 0, this->width(), this->height());
	p.setAntiAlias(true);
	
	r.fRight = r.fLeft + SkScalarMul(r.width(), SkFixedToScalar(percent));
	p.setStyle(SkPaint::kFill_Style);

	p.setColor(SK_ColorDKGRAY);
	p.setShader(fOnShader);
	canvas->drawRect(r, p);

	p.setColor(SK_ColorWHITE);
	p.setShader(fOffShader);
	r.fLeft = r.fRight;
	r.fRight = this->width() - SK_Scalar1;
	if (r.width() > 0)
		canvas->drawRect(r, p);
}

#include "SkImageDecoder.h"

static SkShader* inflate_shader(const char file[])
{
	SkBitmap	bm;

	return SkImageDecoder::DecodeFile(file, &bm) ?
			SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode) :
			NULL;
}

void SkProgressView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
	this->INHERITED::onInflate(dom, node);

	const char* s;

	SkASSERT(fOnShader == NULL);
	SkASSERT(fOffShader == NULL);

	if ((s = dom.findAttr(node, "src-on")) != NULL)
		fOnShader = inflate_shader(s);
	if ((s = dom.findAttr(node, "src-off")) != NULL)
		fOffShader = inflate_shader(s);
	(void)dom.findBool(node, "do-interp", &fDoInterp);
}