blob: 87427fc8f311112dfbd7a5983bb42b87386bb047 [file] [log] [blame]
reed1a9caff2015-09-02 19:05:10 -07001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SampleCode.h"
9#include "SkAnimTimer.h"
10#include "SkDrawable.h"
11#include "SkView.h"
12#include "SkCanvas.h"
13#include "SkDrawable.h"
14#include "SkPath.h"
15#include "SkRandom.h"
16#include "SkRSXform.h"
17#include "SkSurface.h"
18#include "SkGradientShader.h"
19
Brian Osmand1e67e72017-03-15 12:19:37 -040020const SkBlendMode gModes[] = {
21 SkBlendMode::kSrcOver,
22 SkBlendMode::kSrc,
23 SkBlendMode::kSrcIn,
24 SkBlendMode::kSrcOut,
25 SkBlendMode::kSrcATop,
26 SkBlendMode::kDstOver,
27 SkBlendMode::kDstIn,
28 SkBlendMode::kDstOut,
29 SkBlendMode::kDstATop,
reed1a9caff2015-09-02 19:05:10 -070030};
31const int N_Modes = SK_ARRAY_COUNT(gModes);
32
33class HasEventWig : public SkView {
34public:
35 void postWidgetEvent() {
36 SkEvent evt;
37 this->onPrepareWidEvent(&evt);
38 this->postToListeners(evt, 0);
39 }
40
41protected:
42 virtual void onPrepareWidEvent(SkEvent*) {}
43};
44
45static SkRandom gRand;
46
47class PushButtonWig : public HasEventWig {
48 SkString fLabel;
49 SkColor fColor;
50 uint32_t fFast32;
51
52public:
53 PushButtonWig(const char label[], uint32_t fast) : fLabel(label) {
54 fColor = (gRand.nextU() & 0x7F7F7F7F) | SkColorSetARGB(0xFF, 0, 0, 0x80);
55 fFast32 = fast;
56 }
halcanary9d524f22016-03-29 09:03:52 -070057
reed1a9caff2015-09-02 19:05:10 -070058protected:
59 void onPrepareWidEvent(SkEvent* evt) override {
60 evt->setType("push-button");
61 evt->setFast32(fFast32);
62 evt->setString("label", fLabel.c_str());
63 }
64
65// bool onEvent(const SkEvent&) override;
66 void onDraw(SkCanvas* canvas) override {
67 SkRect r;
68 this->getLocalBounds(&r);
69 SkPaint paint;
70 paint.setAntiAlias(true);
71 paint.setColor(fColor);
72 canvas->drawRoundRect(r, 8, 8, paint);
73
74 paint.setColor(0xFFFFFFFF);
75 paint.setTextSize(16);
76 paint.setTextAlign(SkPaint::kCenter_Align);
77 paint.setLCDRenderText(true);
Cary Clark2a475ea2017-04-28 15:35:12 -040078 canvas->drawString(fLabel, r.centerX(), r.fTop + 0.68f * r.height(), paint);
reed1a9caff2015-09-02 19:05:10 -070079 }
80
81 Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
82 return new Click(this);
83 }
84
85 bool onClick(Click* click) override {
86 SkRect target = SkRect::MakeXYWH(click->fCurr.x() - 1, click->fCurr.y() - 1, 3, 3);
87 SkRect r;
88 this->getLocalBounds(&r);
89 if (r.intersects(target)) {
90 fColor = SkColorSetA(fColor, 0x99);
91 } else {
92 fColor = SkColorSetA(fColor, 0xFF);
93 }
94 this->inval(nullptr);
95
96 if (click->fState == SkView::Click::kUp_State) {
97 this->postWidgetEvent();
98 }
99 return true;
100 }
halcanary9d524f22016-03-29 09:03:52 -0700101
reed1a9caff2015-09-02 19:05:10 -0700102private:
103 typedef HasEventWig INHERITED;
104};
105
106
107class ModeDrawable : public SkDrawable {
108public:
reed374772b2016-10-05 17:33:02 -0700109 ModeDrawable() : fMode(SkBlendMode::kSrcOver), fLoc(SkPoint::Make(0, 0)) {}
reed1a9caff2015-09-02 19:05:10 -0700110
reed374772b2016-10-05 17:33:02 -0700111 SkBlendMode fMode;
112 SkPoint fLoc;
reed1a9caff2015-09-02 19:05:10 -0700113
114 bool hitTest(SkScalar x, SkScalar y) {
115 SkRect target = SkRect::MakeXYWH(x - fLoc.x() - 1, y - fLoc.y() - 1, 3, 3);
116 return this->getBounds().intersects(target);
117 }
118};
119
120class CircDrawable : public ModeDrawable {
121 SkPaint fPaint;
122 SkRect fBounds;
123
124public:
125 CircDrawable(SkScalar size, SkColor c) {
126 const SkColor colors[] = { 0, c };
reed8a21c9f2016-03-08 18:50:00 -0800127 fPaint.setShader(SkGradientShader::MakeRadial(SkPoint::Make(size/2, size/2), size/2,
reed1a9caff2015-09-02 19:05:10 -0700128 colors, nullptr, 2,
129 SkShader::kClamp_TileMode));
reed1a9caff2015-09-02 19:05:10 -0700130 fBounds = SkRect::MakeWH(size, size);
131 }
132
133protected:
134 SkRect onGetBounds() override {
135 return fBounds;
136 }
137
138 void onDraw(SkCanvas* canvas) override {
reed374772b2016-10-05 17:33:02 -0700139 fPaint.setBlendMode(fMode);
reed1a9caff2015-09-02 19:05:10 -0700140 canvas->save();
141 canvas->translate(fLoc.x(), fLoc.y());
142 canvas->drawOval(fBounds, fPaint);
143 canvas->restore();
144 }
145};
146
147class XferDemo : public SampleView {
148 enum {
149 N = 4
150 };
halcanary9d524f22016-03-29 09:03:52 -0700151
reed1a9caff2015-09-02 19:05:10 -0700152 SkRect fModeRect[N_Modes];
Hal Canary2db83612016-11-04 13:02:54 -0400153 sk_sp<CircDrawable> fDrs[N];
reed1a9caff2015-09-02 19:05:10 -0700154 CircDrawable* fSelected;
155
156 void addButtons() {
157 SkScalar x = 10;
158 SkScalar y = 10;
159 for (int i = 0; i < N_Modes; ++i) {
Brian Osmand1e67e72017-03-15 12:19:37 -0400160 sk_sp<SkView> v(new PushButtonWig(SkBlendMode_Name(gModes[i]), (int)gModes[i]));
reed1a9caff2015-09-02 19:05:10 -0700161 v->setSize(70, 25);
162 v->setLoc(x, y);
163 v->setVisibleP(true);
164 v->setEnabledP(true);
165 v->addListenerID(this->getSinkID());
Hal Canary2db83612016-11-04 13:02:54 -0400166 this->attachChildToFront(v.get());
reed1a9caff2015-09-02 19:05:10 -0700167 fModeRect[i] = SkRect::MakeXYWH(x, y + 28, 70, 2);
168 x += 80;
169 }
170 }
171
172public:
173 XferDemo() {
174 const SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorBLACK };
175 for (int i = 0; i < N; ++i) {
176 fDrs[i].reset(new CircDrawable(200, colors[i]));
177 fDrs[i]->fLoc.set(100.f + i * 100, 100.f + i * 100);
reed374772b2016-10-05 17:33:02 -0700178 fDrs[i]->fMode = SkBlendMode::kSrcOver;
reed1a9caff2015-09-02 19:05:10 -0700179 }
180 fSelected = nullptr;
181
182 this->addButtons();
183 }
184
185protected:
186 bool onEvent(const SkEvent& evt) override {
187 if (evt.isType("push-button")) {
188 if (fSelected) {
reed374772b2016-10-05 17:33:02 -0700189 fSelected->fMode = (SkBlendMode)evt.getFast32();
reed1a9caff2015-09-02 19:05:10 -0700190 this->inval(nullptr);
191 }
192 return true;
193 }
194 return this->INHERITED::onEvent(evt);
195 }
196
197 bool onQuery(SkEvent* evt) override {
198 if (SampleCode::TitleQ(*evt)) {
199 SampleCode::TitleR(evt, "XferDemo");
200 return true;
201 }
202 return this->INHERITED::onQuery(evt);
203 }
204
205 void onDrawContent(SkCanvas* canvas) override {
206 SkPaint paint;
207 if (fSelected) {
208 for (int i = 0; i < N_Modes; ++i) {
Brian Osmand1e67e72017-03-15 12:19:37 -0400209 if (fSelected->fMode == gModes[i]) {
reed1a9caff2015-09-02 19:05:10 -0700210 canvas->drawRect(fModeRect[i], paint);
211 break;
212 }
213 }
214 }
215
216 canvas->saveLayer(nullptr, nullptr);
217 for (int i = 0; i < N; ++i) {
218 fDrs[i]->draw(canvas);
219 }
220 canvas->restore();
221 }
222
223 SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
224 fSelected = nullptr;
225 for (int i = N - 1; i >= 0; --i) {
226 if (fDrs[i]->hitTest(x, y)) {
Hal Canary2db83612016-11-04 13:02:54 -0400227 fSelected = fDrs[i].get();
reed1a9caff2015-09-02 19:05:10 -0700228 break;
229 }
230 }
231 this->inval(nullptr);
232 return fSelected ? new Click(this) : nullptr;
233 }
halcanary9d524f22016-03-29 09:03:52 -0700234
reed1a9caff2015-09-02 19:05:10 -0700235 bool onClick(Click* click) override {
236 fSelected->fLoc.fX += click->fCurr.fX - click->fPrev.fX;
237 fSelected->fLoc.fY += click->fCurr.fY - click->fPrev.fY;
238 this->inval(nullptr);
239 return true;
240 }
241
242private:
243 typedef SampleView INHERITED;
244};
245
246//////////////////////////////////////////////////////////////////////////////
247
248DEF_SAMPLE( return new XferDemo; )