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