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