| Index: samplecode/SampleXfer.cpp
|
| diff --git a/samplecode/SampleXfer.cpp b/samplecode/SampleXfer.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..221ba5815ea36b4815213c837ce029566abad802
|
| --- /dev/null
|
| +++ b/samplecode/SampleXfer.cpp
|
| @@ -0,0 +1,252 @@
|
| +/*
|
| + * Copyright 2015 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#include "SampleCode.h"
|
| +#include "SkAnimTimer.h"
|
| +#include "SkDrawable.h"
|
| +#include "SkView.h"
|
| +#include "SkCanvas.h"
|
| +#include "SkDrawable.h"
|
| +#include "SkPath.h"
|
| +#include "SkRandom.h"
|
| +#include "SkRSXform.h"
|
| +#include "SkSurface.h"
|
| +#include "SkGradientShader.h"
|
| +
|
| +const struct {
|
| + SkXfermode::Mode fMode;
|
| + const char* fName;
|
| +} gModes[] = {
|
| + { SkXfermode::kSrcOver_Mode, "src-over" },
|
| + { SkXfermode::kSrc_Mode, "src" },
|
| + { SkXfermode::kSrcIn_Mode, "src-in" },
|
| + { SkXfermode::kSrcOut_Mode, "src-out" },
|
| + { SkXfermode::kSrcATop_Mode, "src-atop" },
|
| + { SkXfermode::kDstOver_Mode, "dst-over" },
|
| + { SkXfermode::kDstIn_Mode, "dst-in" },
|
| + { SkXfermode::kDstOut_Mode, "dst-out" },
|
| + { SkXfermode::kDstATop_Mode, "dst-atop" },
|
| +};
|
| +const int N_Modes = SK_ARRAY_COUNT(gModes);
|
| +
|
| +class HasEventWig : public SkView {
|
| +public:
|
| + void postWidgetEvent() {
|
| + SkEvent evt;
|
| + this->onPrepareWidEvent(&evt);
|
| + this->postToListeners(evt, 0);
|
| + }
|
| +
|
| +protected:
|
| + virtual void onPrepareWidEvent(SkEvent*) {}
|
| +};
|
| +
|
| +static SkRandom gRand;
|
| +
|
| +class PushButtonWig : public HasEventWig {
|
| + SkString fLabel;
|
| + SkColor fColor;
|
| + uint32_t fFast32;
|
| +
|
| +public:
|
| + PushButtonWig(const char label[], uint32_t fast) : fLabel(label) {
|
| + fColor = (gRand.nextU() & 0x7F7F7F7F) | SkColorSetARGB(0xFF, 0, 0, 0x80);
|
| + fFast32 = fast;
|
| + }
|
| +
|
| +protected:
|
| + void onPrepareWidEvent(SkEvent* evt) override {
|
| + evt->setType("push-button");
|
| + evt->setFast32(fFast32);
|
| + evt->setString("label", fLabel.c_str());
|
| + }
|
| +
|
| +// bool onEvent(const SkEvent&) override;
|
| + void onDraw(SkCanvas* canvas) override {
|
| + SkRect r;
|
| + this->getLocalBounds(&r);
|
| + SkPaint paint;
|
| + paint.setAntiAlias(true);
|
| + paint.setColor(fColor);
|
| + canvas->drawRoundRect(r, 8, 8, paint);
|
| +
|
| + paint.setColor(0xFFFFFFFF);
|
| + paint.setTextSize(16);
|
| + paint.setTextAlign(SkPaint::kCenter_Align);
|
| + paint.setLCDRenderText(true);
|
| + canvas->drawText(fLabel.c_str(), fLabel.size(), r.centerX(), r.fTop + 0.68f * r.height(), paint);
|
| + }
|
| +
|
| + Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
|
| + return new Click(this);
|
| + }
|
| +
|
| + bool onClick(Click* click) override {
|
| + SkRect target = SkRect::MakeXYWH(click->fCurr.x() - 1, click->fCurr.y() - 1, 3, 3);
|
| + SkRect r;
|
| + this->getLocalBounds(&r);
|
| + if (r.intersects(target)) {
|
| + fColor = SkColorSetA(fColor, 0x99);
|
| + } else {
|
| + fColor = SkColorSetA(fColor, 0xFF);
|
| + }
|
| + this->inval(nullptr);
|
| +
|
| + if (click->fState == SkView::Click::kUp_State) {
|
| + this->postWidgetEvent();
|
| + }
|
| + return true;
|
| + }
|
| +
|
| +private:
|
| + typedef HasEventWig INHERITED;
|
| +};
|
| +
|
| +
|
| +class ModeDrawable : public SkDrawable {
|
| +public:
|
| + ModeDrawable() : fMode(SkXfermode::kSrcOver_Mode), fLoc(SkPoint::Make(0, 0)) {}
|
| +
|
| + SkXfermode::Mode fMode;
|
| + SkPoint fLoc;
|
| +
|
| + bool hitTest(SkScalar x, SkScalar y) {
|
| + SkRect target = SkRect::MakeXYWH(x - fLoc.x() - 1, y - fLoc.y() - 1, 3, 3);
|
| + return this->getBounds().intersects(target);
|
| + }
|
| +};
|
| +
|
| +class CircDrawable : public ModeDrawable {
|
| + SkPaint fPaint;
|
| + SkRect fBounds;
|
| +
|
| +public:
|
| + CircDrawable(SkScalar size, SkColor c) {
|
| + const SkColor colors[] = { 0, c };
|
| + SkAutoTUnref<SkShader> shader(SkGradientShader::CreateRadial(SkPoint::Make(size/2, size/2), size/2,
|
| + colors, nullptr, 2,
|
| + SkShader::kClamp_TileMode));
|
| + fPaint.setShader(shader);
|
| + fBounds = SkRect::MakeWH(size, size);
|
| + }
|
| +
|
| +protected:
|
| + SkRect onGetBounds() override {
|
| + return fBounds;
|
| + }
|
| +
|
| + void onDraw(SkCanvas* canvas) override {
|
| + fPaint.setXfermodeMode(fMode);
|
| + canvas->save();
|
| + canvas->translate(fLoc.x(), fLoc.y());
|
| + canvas->drawOval(fBounds, fPaint);
|
| + canvas->restore();
|
| + }
|
| +};
|
| +
|
| +class XferDemo : public SampleView {
|
| + enum {
|
| + N = 4
|
| + };
|
| +
|
| + SkRect fModeRect[N_Modes];
|
| + SkAutoTUnref<CircDrawable> fDrs[N];
|
| + CircDrawable* fSelected;
|
| +
|
| + void addButtons() {
|
| + SkScalar x = 10;
|
| + SkScalar y = 10;
|
| + for (int i = 0; i < N_Modes; ++i) {
|
| + SkAutoTUnref<SkView> v(new PushButtonWig(gModes[i].fName, gModes[i].fMode));
|
| + v->setSize(70, 25);
|
| + v->setLoc(x, y);
|
| + v->setVisibleP(true);
|
| + v->setEnabledP(true);
|
| + v->addListenerID(this->getSinkID());
|
| + this->attachChildToFront(v);
|
| + fModeRect[i] = SkRect::MakeXYWH(x, y + 28, 70, 2);
|
| + x += 80;
|
| + }
|
| + }
|
| +
|
| +public:
|
| + XferDemo() {
|
| + const SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorBLACK };
|
| + for (int i = 0; i < N; ++i) {
|
| + fDrs[i].reset(new CircDrawable(200, colors[i]));
|
| + fDrs[i]->fLoc.set(100.f + i * 100, 100.f + i * 100);
|
| + fDrs[i]->fMode = SkXfermode::kSrcOver_Mode;
|
| + }
|
| + fSelected = nullptr;
|
| +
|
| + this->addButtons();
|
| + }
|
| +
|
| +protected:
|
| + bool onEvent(const SkEvent& evt) override {
|
| + if (evt.isType("push-button")) {
|
| + if (fSelected) {
|
| + fSelected->fMode = (SkXfermode::Mode)evt.getFast32();
|
| + this->inval(nullptr);
|
| + }
|
| + return true;
|
| + }
|
| + return this->INHERITED::onEvent(evt);
|
| + }
|
| +
|
| + bool onQuery(SkEvent* evt) override {
|
| + if (SampleCode::TitleQ(*evt)) {
|
| + SampleCode::TitleR(evt, "XferDemo");
|
| + return true;
|
| + }
|
| + return this->INHERITED::onQuery(evt);
|
| + }
|
| +
|
| + void onDrawContent(SkCanvas* canvas) override {
|
| + SkPaint paint;
|
| + if (fSelected) {
|
| + for (int i = 0; i < N_Modes; ++i) {
|
| + if (fSelected->fMode == gModes[i].fMode) {
|
| + canvas->drawRect(fModeRect[i], paint);
|
| + break;
|
| + }
|
| + }
|
| + }
|
| +
|
| + canvas->saveLayer(nullptr, nullptr);
|
| + for (int i = 0; i < N; ++i) {
|
| + fDrs[i]->draw(canvas);
|
| + }
|
| + canvas->restore();
|
| + }
|
| +
|
| + SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
|
| + fSelected = nullptr;
|
| + for (int i = N - 1; i >= 0; --i) {
|
| + if (fDrs[i]->hitTest(x, y)) {
|
| + fSelected = fDrs[i];
|
| + break;
|
| + }
|
| + }
|
| + this->inval(nullptr);
|
| + return fSelected ? new Click(this) : nullptr;
|
| + }
|
| +
|
| + bool onClick(Click* click) override {
|
| + fSelected->fLoc.fX += click->fCurr.fX - click->fPrev.fX;
|
| + fSelected->fLoc.fY += click->fCurr.fY - click->fPrev.fY;
|
| + this->inval(nullptr);
|
| + return true;
|
| + }
|
| +
|
| +private:
|
| + typedef SampleView INHERITED;
|
| +};
|
| +
|
| +//////////////////////////////////////////////////////////////////////////////
|
| +
|
| +DEF_SAMPLE( return new XferDemo; )
|
|
|