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 15SkProgressView::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 23SkProgressView::~SkProgressView() 24{ 25 delete fInterp; 26 SkSafeUnref(fOnShader); 27 SkSafeUnref(fOffShader); 28} 29 30void 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 40void 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 59void 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 109static 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 118void 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