#include "SkWidget.h" #include "SkCanvas.h" #include "SkInterpolator.h" #include "SkTime.h" #include "SkParsePaint.h" #if 0 SkWidgetView::SkWidgetView(U32 flags) : SkView(flags) { } SkWidgetView::~SkWidgetView() { } const char* SkWidgetView::GetEventType() { return "SkWidgetView"; } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// class SkTextView::Interp { public: Interp(const SkString& old, SkMSec now, SkMSec dur, AnimaDir dir) : fOldText(old), fInterp(1, 2) { SkScalar x = 0; fInterp.setKeyFrame(0, now, &x, 0); x = SK_Scalar1; if (dir == kBackward_AnimDir) x = -x; fInterp.setKeyFrame(1, now + dur, &x); } bool draw(SkCanvas* canvas, const SkString& newText, SkScalar x, SkScalar y, SkPaint& paint) { SkScalar scale; if (fInterp.timeToValues(SkTime::GetMSecs(), &scale) == SkInterpolator::kFreezeEnd_Result) { canvas->drawText(newText.c_str(), newText.size(), x, y, paint); return false; } else { U8 alpha = paint.getAlpha(); SkScalar above, below; (void)paint.measureText(NULL, 0, &above, &below); SkScalar height = below - above; SkScalar dy = SkScalarMul(height, scale); if (scale < 0) height = -height; // draw the old paint.setAlpha((U8)SkScalarMul(alpha, SK_Scalar1 - SkScalarAbs(scale))); canvas->drawText(fOldText.c_str(), fOldText.size(), x, y - dy, paint); // draw the new paint.setAlpha((U8)SkScalarMul(alpha, SkScalarAbs(scale))); canvas->drawText(newText.c_str(), newText.size(), x, y + height - dy, paint); // restore the paint paint.setAlpha(alpha); return true; } } private: SkString fOldText; SkInterpolator fInterp; }; SkTextView::SkTextView(U32 flags) : SkView(flags), fInterp(NULL), fDoInterp(false) { fMargin.set(0, 0); } SkTextView::~SkTextView() { delete fInterp; } void SkTextView::getText(SkString* str) const { if (str) str->set(fText); } void SkTextView::setText(const char text[], AnimaDir dir) { if (!fText.equals(text)) { SkString tmp(text); this->privSetText(tmp, dir); } } void SkTextView::setText(const char text[], size_t len, AnimaDir dir) { if (!fText.equals(text)) { SkString tmp(text, len); this->privSetText(tmp, dir); } } void SkTextView::setText(const SkString& src, AnimaDir dir) { if (fText != src) this->privSetText(src, dir); } void SkTextView::privSetText(const SkString& src, AnimaDir dir) { SkASSERT(fText != src); if (fDoInterp) { if (fInterp) delete fInterp; fInterp = new Interp(fText, SkTime::GetMSecs(), 500, dir); } fText = src; this->inval(NULL); } ///////////////////////////////////////////////////////////////// void SkTextView::getMargin(SkPoint* margin) const { if (margin) *margin = fMargin; } void SkTextView::setMargin(const SkPoint& margin) { if (fMargin != margin) { fMargin = margin; this->inval(NULL); } } void SkTextView::onDraw(SkCanvas* canvas) { this->INHERITED::onDraw(canvas); if (fText.size() == 0) return; SkPaint::Align align = fPaint.getTextAlign(); SkScalar x, y; switch (align) { case SkPaint::kLeft_Align: x = fMargin.fX; break; case SkPaint::kCenter_Align: x = SkScalarHalf(this->width()); break; default: SkASSERT(align == SkPaint::kRight_Align); x = this->width() - fMargin.fX; break; } fPaint.measureText(NULL, 0, &y, NULL); y = fMargin.fY - y; if (fInterp) { if (fInterp->draw(canvas, fText, x, y, fPaint)) this->inval(NULL); else { delete fInterp; fInterp = NULL; } } else canvas->drawText(fText.c_str(), fText.size(), x, y, fPaint); } ////////////////////////////////////////////////////////////////////////////////////// void SkTextView::onInflate(const SkDOM& dom, const SkDOM::Node* node) { this->INHERITED::onInflate(dom, node); const char* text = dom.findAttr(node, "text"); if (text) this->setText(text); SkPoint margin; if (dom.findScalars(node, "margin", (SkScalar*)&margin, 2)) this->setMargin(margin); (void)dom.findBool(node, "do-interp", &fDoInterp); SkPaint_Inflate(&fPaint, dom, node); } ////////////////////////////////////////////////////////////////////////////////////// SkSliderView::SkSliderView(U32 flags) : SkWidgetView(flags) { fValue = 0; fMax = 0; } static U16 actual_value(U16CPU value, U16CPU max) { return SkToU16(SkMax32(0, SkMin32(value, max))); } void SkSliderView::setMax(U16CPU max) { if (fMax != max) { fMax = SkToU16(max); if (fValue > 0) this->inval(NULL); } } void SkSliderView::setValue(U16CPU value) { if (fValue != value) { U16 prev = actual_value(fValue, fMax); U16 next = actual_value(value, fMax); fValue = SkToU16(value); if (prev != next) { this->inval(NULL); if (this->hasListeners()) { SkEvent evt; evt.setType(SkWidgetView::GetEventType()); evt.setFast32(this->getSinkID()); evt.setS32("sliderValue", next); this->postToListeners(evt); } } } } #include "SkGradientShader.h" static void setgrad(SkPaint* paint, const SkRect& r) { SkPoint pts[2]; SkColor colors[2]; #if 0 pts[0].set(r.fLeft, r.fTop); pts[1].set(r.fLeft + r.height(), r.fBottom); #else pts[0].set(r.fRight, r.fBottom); pts[1].set(r.fRight - r.height(), r.fTop); #endif colors[0] = SK_ColorBLUE; colors[1] = SK_ColorWHITE; paint->setShader(SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kMirror_TileMode))->unref(); } void SkSliderView::onDraw(SkCanvas* canvas) { this->INHERITED::onDraw(canvas); U16CPU value = SkMax32(0, SkMin32(fValue, fMax)); SkRect r; SkPaint p; r.set(0, 0, this->width(), this->height()); p.setAntiAliasOn(true); p.setStyle(SkPaint::kStroke_Style); p.setStrokeWidth(SK_Scalar1); r.inset(SK_Scalar1/2, SK_Scalar1/2); canvas->drawRect(r, p); if (fMax) { SkFixed percent = SkFixedDiv(value, fMax); r.inset(SK_Scalar1/2, SK_Scalar1/2); r.fRight = r.fLeft + SkScalarMul(r.width(), SkFixedToScalar(percent)); p.setStyle(SkPaint::kFill_Style); setgrad(&p, r); canvas->drawRect(r, p); } #if 0 r.set(0, 0, this->width(), this->height()); r.inset(SK_Scalar1, SK_Scalar1); r.inset(r.width()/2, 0); p.setColor(SK_ColorBLACK); canvas->drawLine(*(SkPoint*)&r.fLeft, *(SkPoint*)&r.fRight, p); #endif } SkView::Click* SkSliderView::onFindClickHandler(SkScalar x, SkScalar y) { return new Click(this); } bool SkSliderView::onClick(Click* click) { if (fMax) { SkScalar percent = SkScalarDiv(click->fCurr.fX + SK_Scalar1, this->width() - SK_Scalar1*2); percent = SkMaxScalar(0, SkMinScalar(percent, SK_Scalar1)); this->setValue(SkScalarRound(percent * fMax)); return true; } return false; } #endif