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 */
8b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org#include "SampleCode.h"
9b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org#include "SkView.h"
10b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org#include "SkCanvas.h"
11b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org#include "SkGraphics.h"
12b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org#include "SkRandom.h"
13b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
142f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.comstatic void test_clearonlayers(SkCanvas* canvas) {
152f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    SkCanvas& c = *canvas;
16ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
172f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    SkPaint paint;
182f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    paint.setColor(SK_ColorBLUE);
192f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    paint.setStyle(SkPaint::kStrokeAndFill_Style);
202f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    SkRect rect = SkRect::MakeXYWH(25, 25, 50, 50);
212f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    c.drawRect(rect, paint);
22ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
232f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    c.clipRect(rect);
24ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
252f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    c.saveLayer(NULL, NULL);
262f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    rect = SkRect::MakeXYWH(50, 10, 40, 80);
272f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    c.clipRect(rect, SkRegion::kUnion_Op);
28ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
292f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    rect = SkRect::MakeXYWH(50, 0, 50, 100);
302f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    // You might draw something here, but it's not necessary.
312f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    // paint.setColor(SK_ColorRED);
322f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    // c.drawRect(rect, paint);
332f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    paint.setXfermodeMode(SkXfermode::kClear_Mode);
342f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    c.drawRect(rect, paint);
352f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    c.restore();
362f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com}
372f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com
38a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.orgstatic void test_strokerect(SkCanvas* canvas, const SkRect& r) {
39a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    SkPaint p;
40ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
41a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    p.setAntiAlias(true);
42a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    p.setStyle(SkPaint::kStroke_Style);
43a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    p.setStrokeWidth(4);
44ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
45a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    canvas->drawRect(r, p);
46a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org
47a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    SkPath path;
48a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    SkRect r2(r);
49a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    r2.offset(18, 0);
50a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    path.addRect(r2);
51a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org
52a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    canvas->drawPath(path, p);
53a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org}
54a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org
55a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.orgstatic void test_strokerect(SkCanvas* canvas) {
56a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    canvas->drawColor(SK_ColorWHITE);
57a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org
58a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    SkRect r;
59a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org
60a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    r.set(10, 10, 14, 14);
61261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com    r.offset(0.25f, 0.3333f);
62a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    test_strokerect(canvas, r);
63a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    canvas->translate(0, 20);
64ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
65a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    r.set(10, 10, 14.5f, 14.5f);
66261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com    r.offset(0.25f, 0.3333f);
67a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    test_strokerect(canvas, r);
68a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    canvas->translate(0, 20);
69ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
70a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    r.set(10, 10, 14.5f, 20);
71261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com    r.offset(0.25f, 0.3333f);
72a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    test_strokerect(canvas, r);
73a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    canvas->translate(0, 20);
74ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
75a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    r.set(10, 10, 20, 14.5f);
76261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com    r.offset(0.25f, 0.3333f);
77a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    test_strokerect(canvas, r);
78a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    canvas->translate(0, 20);
79ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
80a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    r.set(10, 10, 20, 20);
81261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com    r.offset(0.25f, 0.3333f);
82a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    test_strokerect(canvas, r);
83a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    canvas->translate(0, 20);
84ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
85a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org}
86a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org
87b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgclass Draw : public SkRefCnt {
88b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgpublic:
89dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    Draw() : fFlags(0) {}
90dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
91dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    enum Flags {
92dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        kSelected_Flag  = 1 << 0
93dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    };
94dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    int getFlags() const { return fFlags; }
95dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    void setFlags(int flags);
96dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
97dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    bool isSelected() const { return SkToBool(fFlags & kSelected_Flag); }
98dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    void setSelected(bool pred) {
99dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        if (pred) {
100dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            fFlags |= kSelected_Flag;
101dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        } else {
102dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            fFlags &= ~kSelected_Flag;
103dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        }
104dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
105dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
106b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    void draw(SkCanvas* canvas) {
107dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        int sc = canvas->save();
108b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        this->onDraw(canvas);
109dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        canvas->restoreToCount(sc);
110dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
111dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        if (this->isSelected()) {
112dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            this->drawSelection(canvas);
113dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        }
114dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
115dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
116dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    void drawSelection(SkCanvas* canvas) {
117dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        int sc = canvas->save();
118dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        this->onDrawSelection(canvas);
119dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        canvas->restoreToCount(sc);
120dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
121dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
122dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    void getBounds(SkRect* bounds) {
123dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        this->onGetBounds(bounds);
124dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
125dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
126dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    bool hitTest(SkScalar x, SkScalar y) {
127dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        return this->onHitTest(x, y);
128dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
129dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
130dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    void offset(SkScalar dx, SkScalar dy) {
131dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        if (dx || dy) {
132dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            this->onOffset(dx, dy);
133dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        }
134b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
135b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
136b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgprotected:
137b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    virtual void onDraw(SkCanvas*) = 0;
138dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    virtual void onGetBounds(SkRect*) = 0;
139dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    virtual void onOffset(SkScalar dx, SkScalar dy) = 0;
140dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    virtual void onDrawSelection(SkCanvas* canvas) {
141dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        SkRect r;
142dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        this->getBounds(&r);
143dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        SkPaint paint;
144dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        SkPoint pts[4];
145dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        r.toQuad(pts);
146dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        paint.setStrokeWidth(SkIntToScalar(10));
147dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        paint.setColor(0x80FF8844);
148dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        paint.setStrokeCap(SkPaint::kRound_Cap);
149dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, pts, paint);
150dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
151dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    virtual bool onHitTest(SkScalar x, SkScalar y) {
152dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        SkRect bounds;
153dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        this->getBounds(&bounds);
154dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        return bounds.contains(x, y);
155dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
156dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
157dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.orgprivate:
158dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    int fFlags;
159b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org};
160b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
161b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgclass RDraw : public Draw {
162b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgpublic:
163b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    enum Style {
164b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        kRect_Style,
165b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        kOval_Style,
166a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org        kRRect_Style,
167a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org        kFrame_Style
168b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    };
169b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
170b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    RDraw(const SkRect& r, Style s) : fRect(r), fStyle(s) {}
171b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
172b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    void setRect(const SkRect& r) {
173b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        fRect = r;
174b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
175b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
176b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    void setPaint(const SkPaint& p) {
177b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        fPaint = p;
178b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
179b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
180b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgprotected:
181b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    virtual void onDraw(SkCanvas* canvas) {
182b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        switch (fStyle) {
183b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org            case kRect_Style:
184b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org                canvas->drawRect(fRect, fPaint);
185b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org                break;
186b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org            case kOval_Style:
187b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org                canvas->drawOval(fRect, fPaint);
188b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org                break;
189b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org            case kRRect_Style: {
190b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org                SkScalar rx = fRect.width() / 5;
191b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org                SkScalar ry = fRect.height() / 5;
192b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org                if (rx < ry) {
193b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org                    ry = rx;
194b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org                } else {
195b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org                    rx = ry;
196b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org                }
197b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org                canvas->drawRoundRect(fRect, rx, ry, fPaint);
198b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org                break;
199b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org            }
200a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org            case kFrame_Style: {
201a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org                SkPath path;
202a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org                path.addOval(fRect, SkPath::kCW_Direction);
203a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org                SkRect r = fRect;
204a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org                r.inset(fRect.width()/6, 0);
205a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org                path.addOval(r, SkPath::kCCW_Direction);
206a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org                canvas->drawPath(path, fPaint);
207a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org                break;
208a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org            }
209b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        }
210b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
211b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
212dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    virtual void onGetBounds(SkRect* bounds) {
213dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        *bounds = fRect;
214dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
215dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
216dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    virtual void onOffset(SkScalar dx, SkScalar dy) {
217dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        fRect.offset(dx, dy);
218dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
219dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
220b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgprivate:
221b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    SkRect  fRect;
222b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    SkPaint fPaint;
223b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    Style   fStyle;
224b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org};
225b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
226b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgclass DrawFactory {
227b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgpublic:
228b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    DrawFactory() {
229b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        fPaint.setAntiAlias(true);
230b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
231b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
232b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    const SkPaint& getPaint() const { return fPaint; }
233b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
234b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    void setPaint(const SkPaint& p) {
235b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        fPaint = p;
236b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
237b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
238b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    virtual Draw* create(const SkPoint&, const SkPoint&) = 0;
239ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
240b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgprivate:
241b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    SkPaint fPaint;
242b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org};
243b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
244b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgclass RectFactory : public DrawFactory {
245b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgpublic:
246b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    virtual Draw* create(const SkPoint& p0, const SkPoint& p1) {
247b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        SkRect r;
248b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        r.set(p0.x(), p0.y(), p1.x(), p1.y());
249b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        r.sort();
250b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
251a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org//        RDraw* d = new RDraw(r, RDraw::kRRect_Style);
252a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org        RDraw* d = new RDraw(r, RDraw::kFrame_Style);
253b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        d->setPaint(this->getPaint());
254b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        return d;
255b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
256b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org};
257b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
258b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgclass DrawView : public SkView {
259b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    Draw*           fDraw;
260b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    DrawFactory*    fFactory;
261b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    SkRandom        fRand;
262b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    SkTDArray<Draw*> fList;
263b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
264b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgpublic:
265b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    DrawView() : fDraw(NULL) {
266b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        fFactory = new RectFactory;
267b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
268b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
269b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    virtual ~DrawView() {
270b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        fList.unrefAll();
271b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        SkSafeUnref(fDraw);
2721d5aaa8ef65f312508e41ec458d4a6457f9cd39ereed@google.com        delete fFactory;
273b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
274b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
275b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    Draw* setDraw(Draw* d) {
276b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        SkRefCnt_SafeAssign(fDraw, d);
277b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        return d;
278b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
279b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
280b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    SkColor randColor() {
281b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        return (SkColor)fRand.nextU() | 0xFF000000;
282b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
283b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
284dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    Draw* hitTestList(SkScalar x, SkScalar y) const {
285dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        Draw** first = fList.begin();
286dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        for (Draw** iter = fList.end(); iter > first;) {
287dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            --iter;
288dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            if ((*iter)->hitTest(x, y)) {
289dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                return *iter;
290dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            }
291dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        }
292dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        return NULL;
293dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
294ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
295b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgprotected:
296b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    // overrides from SkEventSink
297b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    virtual bool onQuery(SkEvent* evt) {
298b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        if (SampleCode::TitleQ(*evt)) {
299b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org            SampleCode::TitleR(evt, "Draw");
300b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org            return true;
301b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        }
302b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        return this->INHERITED::onQuery(evt);
303b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
304b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
305b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    void drawBG(SkCanvas* canvas) {
306b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        canvas->drawColor(0xFFDDDDDD);
307b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org//        canvas->drawColor(SK_ColorWHITE);
308b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
309b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
310b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    virtual void onDraw(SkCanvas* canvas) {
311b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        this->drawBG(canvas);
3122f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com        test_clearonlayers(canvas); return;
3132f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com     //   test_strokerect(canvas); return;
314b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
315dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        for (Draw** iter = fList.begin(); iter < fList.end(); iter++) {
316b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org            (*iter)->draw(canvas);
317b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        }
318b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        if (fDraw) {
319b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org            fDraw->draw(canvas);
320b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        }
321b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
322b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
323b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
324dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        for (Draw** iter = fList.begin(); iter < fList.end(); iter++) {
325dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            (*iter)->setSelected(false);
326dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        }
327dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
328dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        Click* c = new Click(this);
329dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        Draw* d = this->hitTestList(x, y);
330dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        if (d) {
331dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            d->setSelected(true);
332dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            c->setType("dragger");
333dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        } else {
334dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            c->setType("maker");
335dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        }
336dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        return c;
337b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
338b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
339b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    virtual bool onClick(Click* click) {
340b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        if (Click::kUp_State == click->fState) {
341dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            if (click->isType("maker")) {
342dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                if (SkPoint::Distance(click->fOrig, click->fCurr) > SkIntToScalar(3)) {
343dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                    *fList.append() = fDraw;
344dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                } else {
345dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                    fDraw->unref();
346dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                }
347dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                fDraw = NULL;
348dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            }
349b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org            return true;
350b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        }
351b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
352b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        if (Click::kDown_State == click->fState) {
353b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org            SkPaint p = fFactory->getPaint();
354b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org            p.setColor(this->randColor());
355b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org            fFactory->setPaint(p);
356b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        }
357dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
358dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        if (click->isType("maker")) {
359dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            this->setDraw(fFactory->create(click->fOrig, click->fCurr))->unref();
360dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        } else if (click->isType("dragger")) {
361dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            for (Draw** iter = fList.begin(); iter < fList.end(); iter++) {
362dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                if ((*iter)->isSelected()) {
363dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                    (*iter)->offset(click->fCurr.x() - click->fPrev.x(),
364dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                                    click->fCurr.y() - click->fPrev.y());
365dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                }
366dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            }
367dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        }
368b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        this->inval(NULL);
369b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org        return true;
370b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    }
371b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
372b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgprivate:
373b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    typedef SkView INHERITED;
374b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org};
375b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
376b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org//////////////////////////////////////////////////////////////////////////////
377b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org
378b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgstatic SkView* MyFactory() { return new DrawView; }
379b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.orgstatic SkViewRegister reg(MyFactory);
380