diff options
Diffstat (limited to 'src/views/SkWidget.cpp')
-rw-r--r-- | src/views/SkWidget.cpp | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/src/views/SkWidget.cpp b/src/views/SkWidget.cpp new file mode 100644 index 0000000000..8d945f171a --- /dev/null +++ b/src/views/SkWidget.cpp @@ -0,0 +1,323 @@ +#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(nil, 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(nil), 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(nil); +} + +///////////////////////////////////////////////////////////////// + +void SkTextView::getMargin(SkPoint* margin) const +{ + if (margin) + *margin = fMargin; +} + +void SkTextView::setMargin(const SkPoint& margin) +{ + if (fMargin != margin) + { + fMargin = margin; + this->inval(nil); + } +} + +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(nil, 0, &y, nil); + y = fMargin.fY - y; + + if (fInterp) + { + if (fInterp->draw(canvas, fText, x, y, fPaint)) + this->inval(nil); + else + { + delete fInterp; + fInterp = nil; + } + } + 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(nil); + } +} + +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(nil); + + 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, nil, 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 + |