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