1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2015 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SampleCode.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkAnimTimer.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGradientShader.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPatchUtils.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPerlinNoiseShader.h"
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void draw_control_points(SkCanvas* canvas, const SkPoint cubics[12]) {
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    //draw control points
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint paint;
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint bottom[SkPatchUtils::kNumPtsCubic];
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPatchUtils::GetBottomCubic(cubics, bottom);
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint top[SkPatchUtils::kNumPtsCubic];
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPatchUtils::GetTopCubic(cubics, top);
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint left[SkPatchUtils::kNumPtsCubic];
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPatchUtils::GetLeftCubic(cubics, left);
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint right[SkPatchUtils::kNumPtsCubic];
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPatchUtils::GetRightCubic(cubics, right);
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(SK_ColorBLACK);
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setStrokeWidth(0.5f);
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint corners[4] = { bottom[0], bottom[3], top[0], top[3] };
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, bottom, paint);
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, bottom + 1, paint);
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, top, paint);
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, left, paint);
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, right, paint);
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, top + 1, paint);
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, left + 1, paint);
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, right + 1, paint);
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setStrokeWidth(2);
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(SK_ColorRED);
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, corners, paint);
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(SK_ColorBLUE);
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, bottom + 1, paint);
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(SK_ColorCYAN);
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, top + 1, paint);
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(SK_ColorYELLOW);
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, left + 1, paint);
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(SK_ColorGREEN);
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, right + 1, paint);
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// These are actually half the total width and hieghts
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconst SkScalar TexWidth = 100.0f;
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconst SkScalar TexHeight = 100.0f;
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass PerlinPatchView : public SampleView {
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkShader> fShader0;
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkShader> fShader1;
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkShader> fShaderCompose;
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar fXFreq;
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar fYFreq;
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar fSeed;
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint  fPts[SkPatchUtils::kNumCtrlPts];
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar fTexX;
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar fTexY;
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar fTexScale;
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkMatrix fInvMatrix;
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool     fShowGrid = false;
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    PerlinPatchView() : fXFreq(0.025f), fYFreq(0.025f), fSeed(0.0f),
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        fTexX(100.0), fTexY(50.0), fTexScale(1.0f) {
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkScalar s = 2;
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // The order of the colors and points is clockwise starting at upper-left corner.
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        //top points
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPts[0].set(100 * s, 100 * s);
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPts[1].set(150 * s, 50 * s);
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPts[2].set(250 * s, 150 * s);
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPts[3].set(300 * s, 100 * s);
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        //right points
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPts[4].set(275 * s, 150 * s);
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPts[5].set(350 * s, 250 * s);
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        //bottom points
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPts[6].set(300 * s, 300 * s);
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPts[7].set(250 * s, 250 * s);
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        //left points
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPts[8].set(150 * s, 350 * s);
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPts[9].set(100 * s, 300 * s);
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPts[10].set(50 * s, 250 * s);
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPts[11].set(150 * s, 150 * s);
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkColor colors[SkPatchUtils::kNumCorners] = {
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            0xFF5555FF, 0xFF8888FF, 0xFFCCCCFF
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkPoint points[2] = { SkPoint::Make(0.0f, 0.0f),
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    SkPoint::Make(100.0f, 100.0f) };
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fShader0 = SkGradientShader::MakeLinear(points,
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                  colors,
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                  nullptr,
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                  3,
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                  SkShader::kMirror_TileMode,
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                  0,
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                  nullptr);
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // overrides from SkEventSink
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool onQuery(SkEvent* evt)  override {
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (SampleCode::TitleQ(*evt)) {
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SampleCode::TitleR(evt, "PerlinPatch");
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return true;
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkUnichar uni;
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (SampleCode::CharQ(*evt, &uni)) {
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            switch (uni) {
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case 'g': fShowGrid = !fShowGrid; return true;
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                default: break;
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return this->INHERITED::onQuery(evt);
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool onAnimate(const SkAnimTimer& timer) override {
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fSeed += 0.005f;
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return true;
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onDrawContent(SkCanvas* canvas) override {
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!canvas->getTotalMatrix().invert(&fInvMatrix)) {
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return;
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint paint;
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar texWidth = fTexScale * TexWidth;
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar texHeight = fTexScale * TexHeight;
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkPoint texCoords[SkPatchUtils::kNumCorners] = {
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { fTexX - texWidth, fTexY - texHeight},
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { fTexX + texWidth, fTexY - texHeight},
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { fTexX + texWidth, fTexY + texHeight},
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { fTexX - texWidth, fTexY + texHeight}}
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ;
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar scaleFreq = 2.0;
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fShader1 = SkPerlinNoiseShader::MakeImprovedNoise(fXFreq/scaleFreq, fYFreq/scaleFreq, 4,
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                             fSeed);
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fShaderCompose = SkShader::MakeComposeShader(fShader0, fShader1, SkBlendMode::kSrcOver);
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setShader(fShaderCompose);
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkPoint* tex = texCoords;
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fShowGrid) {
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            tex = nullptr;
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawPatch(fPts, nullptr, tex, SkBlendMode::kSrc, paint);
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_control_points(canvas, fPts);
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    class PtClick : public Click {
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    public:
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int fIndex;
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        PtClick(SkView* view, int index) : Click(view), fIndex(index) {}
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static bool hittest(const SkPoint& pt, SkScalar x, SkScalar y) {
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkPoint::Length(pt.fX - x, pt.fY - y) < SkIntToScalar(5);
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // holding down shift
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (1 == modi) {
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return new PtClick(this, -1);
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // holding down ctrl
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (2 == modi) {
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return new PtClick(this, -2);
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint clickPoint = {x, y};
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInvMatrix.mapPoints(&clickPoint, 1);
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); i++) {
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (hittest(fPts[i], clickPoint.fX, clickPoint.fY)) {
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return new PtClick(this, (int)i);
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return this->INHERITED::onFindClickHandler(x, y, modi);
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool onClick(Click* click) override {
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        PtClick* ptClick = (PtClick*)click;
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (ptClick->fIndex >= 0) {
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fPts[ptClick->fIndex].set(click->fCurr.fX , click->fCurr.fY );
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else if (-1 == ptClick->fIndex) {
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkScalar xDiff = click->fPrev.fX - click->fCurr.fX;
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkScalar yDiff = click->fPrev.fY - click->fCurr.fY;
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fTexX += xDiff * fTexScale;
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fTexY += yDiff * fTexScale;
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else if (-2 == ptClick->fIndex) {
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkScalar yDiff = click->fCurr.fY - click->fPrev.fY;
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fTexScale += yDiff / 10.0f;
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fTexScale = SkTMax(0.1f, SkTMin(20.f, fTexScale));
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return true;
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef SampleView INHERITED;
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_SAMPLE( return new PerlinPatchView(); )
218