1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkWidget.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
10889bd8bd7f604acae0a6303365bc82c06da1e6f3tomhudson@google.com#include "SkMath.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkInterpolator.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTime.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkProgressView::SkProgressView(uint32_t flags) : SkView(flags), fOnShader(NULL), fOffShader(NULL)
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
17d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fValue = 0;
18d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fMax = 0;
19d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fInterp = NULL;
20d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fDoInterp = false;
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkProgressView::~SkProgressView()
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
25d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    delete fInterp;
26d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkSafeUnref(fOnShader);
27d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkSafeUnref(fOffShader);
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkProgressView::setMax(U16CPU max)
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
32d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fMax != max)
33d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
34d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fMax = SkToU16(max);
35d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (fValue > 0)
36d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            this->inval(NULL);
37d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkProgressView::setValue(U16CPU value)
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
42d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fValue != value)
43d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
44d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (fDoInterp)
45d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        {
46d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            if (fInterp)
47d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                delete fInterp;
48d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            fInterp = new SkInterpolator(1, 2);
49d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            SkScalar x = (SkScalar)(fValue << 8);
50d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            fInterp->setKeyFrame(0, SkTime::GetMSecs(), &x, 0);
51d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            x = (SkScalar)(value << 8);
52d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            fInterp->setKeyFrame(1, SkTime::GetMSecs() + 333, &x);
53d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        }
54d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fValue = SkToU16(value);
55d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        this->inval(NULL);
56d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkProgressView::onDraw(SkCanvas* canvas)
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
61d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fMax == 0)
62d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        return;
63d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
64d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkFixed    percent;
65d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
66d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fInterp)
67d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
68d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkScalar x;
69d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (fInterp->timeToValues(SkTime::GetMSecs(), &x) == SkInterpolator::kFreezeEnd_Result)
70d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        {
71d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            delete fInterp;
72d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            fInterp = NULL;
73d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        }
74d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        percent = (SkFixed)x;    // now its 16.8
75d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        percent = SkMax32(0, SkMin32(percent, fMax << 8));    // now its pinned
76d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        percent = SkFixedDiv(percent, fMax << 8);    // now its 0.16
77d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        this->inval(NULL);
78d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
79d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    else
80d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
81d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        U16CPU value = SkMax32(0, SkMin32(fValue, fMax));
82d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        percent = SkFixedDiv(value, fMax);
83d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
84d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
85d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
86d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkRect    r;
87d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkPaint    p;
88d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
89d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    r.set(0, 0, this->width(), this->height());
90d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    p.setAntiAlias(true);
91d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
92d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    r.fRight = r.fLeft + SkScalarMul(r.width(), SkFixedToScalar(percent));
93d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    p.setStyle(SkPaint::kFill_Style);
94d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
95d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    p.setColor(SK_ColorDKGRAY);
96d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    p.setShader(fOnShader);
97d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    canvas->drawRect(r, p);
98d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
99d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    p.setColor(SK_ColorWHITE);
100d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    p.setShader(fOffShader);
101d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    r.fLeft = r.fRight;
102d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    r.fRight = this->width() - SK_Scalar1;
103d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (r.width() > 0)
104d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        canvas->drawRect(r, p);
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkImageDecoder.h"
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkShader* inflate_shader(const char file[])
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
111d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkBitmap    bm;
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
113d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return SkImageDecoder::DecodeFile(file, &bm) ?
114d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode) :
115d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            NULL;
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkProgressView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
120d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    this->INHERITED::onInflate(dom, node);
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
122d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    const char* s;
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
124d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(fOnShader == NULL);
125d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(fOffShader == NULL);
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
127d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if ((s = dom.findAttr(node, "src-on")) != NULL)
128d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fOnShader = inflate_shader(s);
129d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if ((s = dom.findAttr(node, "src-off")) != NULL)
130d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fOffShader = inflate_shader(s);
131d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    (void)dom.findBool(node, "do-interp", &fDoInterp);
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
133