blob: 50c626e7b7e0b8d35ca6f8945e305aef437c0f71 [file] [log] [blame]
jvanverthe1a3bc62016-08-12 10:40:38 -07001
2/*
3 * Copyright 2016 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkCanvas.h"
9#include "include/core/SkColorFilter.h"
10#include "include/core/SkPath.h"
11#include "include/core/SkPoint3.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/pathops/SkPathOps.h"
13#include "include/utils/SkCamera.h"
14#include "include/utils/SkShadowUtils.h"
15#include "samplecode/Sample.h"
16#include "src/core/SkBlurMask.h"
17#include "src/utils/SkUTF.h"
18#include "tools/ToolUtils.h"
Hal Canary41248072019-07-11 16:32:53 -040019#include "tools/timer/TimeUtils.h"
jvanverthe1a3bc62016-08-12 10:40:38 -070020
jvanverth6c177a12016-08-17 07:59:41 -070021////////////////////////////////////////////////////////////////////////////
22
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040023class ShadowsView : public Sample {
jvanverthe1a3bc62016-08-12 10:40:38 -070024 SkPath fRectPath;
25 SkPath fRRPath;
26 SkPath fCirclePath;
Jim Van Verthbce74962017-01-25 09:39:46 -050027 SkPath fFunkyRRPath;
28 SkPath fCubicPath;
Jim Van Verth872da6b2018-04-10 11:24:11 -040029 SkPath fStarPath;
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050030 SkPath fSquareRRectPath;
31 SkPath fWideRectPath;
32 SkPath fWideOvalPath;
Jim Van Verth872da6b2018-04-10 11:24:11 -040033 SkPath fNotchPath;
34 SkPath fTabPath;
35
jvanverthe1a3bc62016-08-12 10:40:38 -070036 SkPoint3 fLightPos;
Hal Canaryd7639af2019-07-17 09:08:11 -040037 SkScalar fZDelta = 0;
38 SkScalar fAnimTranslate = 0;
39 SkScalar fAnimAngle = 0;
40 SkScalar fAnimAlpha = 1;
jvanverthe1a3bc62016-08-12 10:40:38 -070041
Hal Canaryd7639af2019-07-17 09:08:11 -040042 bool fShowAmbient = true;
43 bool fShowSpot = true;
44 bool fUseAlt = false;
45 bool fShowObject = true;
46 bool fIgnoreShadowAlpha = false;
47 bool fDoAlphaAnimation = false;
jvanverthe1a3bc62016-08-12 10:40:38 -070048
jvanverthe1a3bc62016-08-12 10:40:38 -070049 void onOnceBeforeDraw() override {
50 fCirclePath.addCircle(0, 0, 50);
51 fRectPath.addRect(SkRect::MakeXYWH(-100, -50, 200, 100));
52 fRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-100, -50, 200, 100), 4, 4));
Mike Reed4241f5e2019-09-14 19:13:23 +000053 fFunkyRRPath.addRoundRect(SkRect::MakeXYWH(-50, -50, SK_Scalar1 * 100, SK_Scalar1 * 100),
54 40 * SK_Scalar1, 20 * SK_Scalar1,
Mike Reed30bc5272019-11-22 18:34:02 +000055 SkPathDirection::kCW);
Jim Van Verthbce74962017-01-25 09:39:46 -050056 fCubicPath.cubicTo(100 * SK_Scalar1, 50 * SK_Scalar1,
57 20 * SK_Scalar1, 100 * SK_Scalar1,
58 0 * SK_Scalar1, 0 * SK_Scalar1);
Jim Van Verth872da6b2018-04-10 11:24:11 -040059 fStarPath.moveTo(0.0f, -50.0f);
60 fStarPath.lineTo(14.43f, -25.0f);
61 fStarPath.lineTo(43.30f, -25.0f);
62 fStarPath.lineTo(28.86f, 0.0f);
63 fStarPath.lineTo(43.30f, 25.0f);
64 fStarPath.lineTo(14.43f, 25.0f);
65 fStarPath.lineTo(0.0f, 50.0f);
66 fStarPath.lineTo(-14.43f, 25.0f);
67 fStarPath.lineTo(-43.30f, 25.0f);
68 fStarPath.lineTo(-28.86f, 0.0f);
69 fStarPath.lineTo(-43.30f, -25.0f);
70 fStarPath.lineTo(-14.43f, -25.0f);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050071 fSquareRRectPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-50, -50, 100, 100),
72 10, 10));
73 fWideRectPath.addRect(SkRect::MakeXYWH(0, 0, 630, 70));
74 fWideOvalPath.addOval(SkRect::MakeXYWH(0, 0, 630, 70));
Jim Van Verthbce74962017-01-25 09:39:46 -050075
Jim Van Verth872da6b2018-04-10 11:24:11 -040076 fNotchPath.moveTo(0, 80);
77 fNotchPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), -90, -90, false);
78 fNotchPath.lineTo(-75, 100);
79 fNotchPath.lineTo(-75, -100);
80 fNotchPath.lineTo(75, -100);
81 fNotchPath.lineTo(75, 100);
82 fNotchPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), 0, -90, false);
83
84 fTabPath.moveTo(-75, -100);
85 fTabPath.lineTo(75, -100);
86 fTabPath.lineTo(75, 100);
87 fTabPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), 0, 90, false);
88 fTabPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), 90, 90, false);
89 fTabPath.lineTo(-75, 100);
90
Jim Van Verthb6069df2017-04-28 11:00:35 -040091 fLightPos = SkPoint3::Make(350, 0, 600);
jvanverthe1a3bc62016-08-12 10:40:38 -070092 }
93
Hal Canary8a027312019-07-03 10:55:44 -040094 SkString name() override { return SkString("AndroidShadows"); }
jvanverthe1a3bc62016-08-12 10:40:38 -070095
Hal Canary6cc65e12019-07-03 15:53:04 -040096 bool onChar(SkUnichar uni) override {
Jim Van Verth6f449692017-02-14 15:16:46 -050097 bool handled = false;
jvanverthe1a3bc62016-08-12 10:40:38 -070098 switch (uni) {
Jim Van Verth2aa535e2017-02-06 14:36:01 -050099 case 'W':
jvanverthe1a3bc62016-08-12 10:40:38 -0700100 fShowAmbient = !fShowAmbient;
Jim Van Verth6f449692017-02-14 15:16:46 -0500101 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700102 break;
103 case 'S':
104 fShowSpot = !fShowSpot;
Jim Van Verth6f449692017-02-14 15:16:46 -0500105 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700106 break;
jvanverthd7315f912016-08-17 10:06:18 -0700107 case 'T':
108 fUseAlt = !fUseAlt;
Jim Van Verth6f449692017-02-14 15:16:46 -0500109 handled = true;
jvanverthd7315f912016-08-17 10:06:18 -0700110 break;
jvanverthe1a3bc62016-08-12 10:40:38 -0700111 case 'O':
112 fShowObject = !fShowObject;
Jim Van Verth6f449692017-02-14 15:16:46 -0500113 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700114 break;
Jim Van Verth744cbb32017-12-19 13:02:38 -0500115 case 'N':
116 fDoAlphaAnimation = !fDoAlphaAnimation;
117 if (!fDoAlphaAnimation) {
118 fAnimAlpha = 1;
119 }
120 handled = true;
121 break;
jvanverthe1a3bc62016-08-12 10:40:38 -0700122 case '>':
Jim Van Verth2aa535e2017-02-06 14:36:01 -0500123 fZDelta += 0.5f;
Jim Van Verth6f449692017-02-14 15:16:46 -0500124 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700125 break;
126 case '<':
Jim Van Verth2aa535e2017-02-06 14:36:01 -0500127 fZDelta -= 0.5f;
Jim Van Verth6f449692017-02-14 15:16:46 -0500128 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700129 break;
Robert Phillips95304e32016-10-07 14:44:07 -0400130 case '?':
131 fIgnoreShadowAlpha = !fIgnoreShadowAlpha;
Jim Van Verth6f449692017-02-14 15:16:46 -0500132 handled = true;
Robert Phillips95304e32016-10-07 14:44:07 -0400133 break;
jvanverthe1a3bc62016-08-12 10:40:38 -0700134 default:
135 break;
136 }
Jim Van Verth6f449692017-02-14 15:16:46 -0500137 if (handled) {
Jim Van Verth6f449692017-02-14 15:16:46 -0500138 return true;
139 }
Hal Canary6cc65e12019-07-03 15:53:04 -0400140 return false;
jvanverthe1a3bc62016-08-12 10:40:38 -0700141 }
142
Jim Van Verthda965502017-04-11 15:29:14 -0400143 void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
Jim Van Verthe308a122017-05-08 14:19:30 -0400144 const SkPoint3& zPlaneParams,
jvanverthd7315f912016-08-17 10:06:18 -0700145 const SkPaint& paint, SkScalar ambientAlpha,
146 const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
Jim Van Verthe7705782017-05-04 14:00:59 -0400147 if (fIgnoreShadowAlpha) {
Jim Van Verth872da6b2018-04-10 11:24:11 -0400148 ambientAlpha = 1;
149 spotAlpha = 1;
Jim Van Verthe7705782017-05-04 14:00:59 -0400150 }
Jim Van Verth060d9822017-05-04 09:58:17 -0400151 if (!fShowAmbient) {
152 ambientAlpha = 0;
153 }
154 if (!fShowSpot) {
155 spotAlpha = 0;
156 }
157 uint32_t flags = 0;
Jim Van Verth3c1b7db2016-10-31 16:06:51 -0400158 if (fUseAlt) {
Jim Van Verth060d9822017-05-04 09:58:17 -0400159 flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
Jim Van Verth3c1b7db2016-10-31 16:06:51 -0400160 }
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400161
Jim Van Vertha5566842018-02-22 10:58:34 -0500162 SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 0, 0, 0);
163 SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
164 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams, lightPos, lightWidth,
165 ambientColor, spotColor, flags);
Jim Van Verth3c1b7db2016-10-31 16:06:51 -0400166
jvanverthe1a3bc62016-08-12 10:40:38 -0700167 if (fShowObject) {
168 canvas->drawPath(path, paint);
Robert Phillips95304e32016-10-07 14:44:07 -0400169 } else {
170 SkPaint strokePaint;
171
172 strokePaint.setColor(paint.getColor());
173 strokePaint.setStyle(SkPaint::kStroke_Style);
174
175 canvas->drawPath(path, strokePaint);
jvanverthe1a3bc62016-08-12 10:40:38 -0700176 }
177 }
178
179 void onDrawContent(SkCanvas* canvas) override {
Hal Canaryd7639af2019-07-17 09:08:11 -0400180 canvas->drawColor(0xFFDDDDDD);
181
Jim Van Verthb6069df2017-04-28 11:00:35 -0400182 const SkScalar kLightWidth = 800;
Jim Van Verth4c8c1e82018-04-23 17:14:48 -0400183 const SkScalar kAmbientAlpha = 0.039f;
184 const SkScalar kSpotAlpha = 0.19f;
jvanverthe1a3bc62016-08-12 10:40:38 -0700185
186 SkPaint paint;
187 paint.setAntiAlias(true);
188
jvanverthd7315f912016-08-17 10:06:18 -0700189 SkPoint3 lightPos = fLightPos;
Jim Van Verthe308a122017-05-08 14:19:30 -0400190 SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, 0);
jvanverthd7315f912016-08-17 10:06:18 -0700191
jvanverthe1a3bc62016-08-12 10:40:38 -0700192 paint.setColor(SK_ColorWHITE);
193 canvas->translate(200, 90);
Brian Osman788b9162020-02-07 10:36:46 -0500194 zPlaneParams.fZ = std::max(1.0f, 2 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500195 this->drawShadowedPath(canvas, fRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
196 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
jvanverthe1a3bc62016-08-12 10:40:38 -0700197
198 paint.setColor(SK_ColorRED);
199 canvas->translate(250, 0);
Brian Osman788b9162020-02-07 10:36:46 -0500200 zPlaneParams.fZ = std::max(1.0f, 8 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500201 this->drawShadowedPath(canvas, fRectPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
202 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
jvanverthe1a3bc62016-08-12 10:40:38 -0700203
204 paint.setColor(SK_ColorBLUE);
205 canvas->translate(-250, 110);
Brian Osman788b9162020-02-07 10:36:46 -0500206 zPlaneParams.fZ = std::max(1.0f, 12 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500207 this->drawShadowedPath(canvas, fCirclePath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
208 lightPos, kLightWidth, fAnimAlpha*0.5f);
jvanverth6c177a12016-08-17 07:59:41 -0700209
210 paint.setColor(SK_ColorGREEN);
211 canvas->translate(250, 0);
Brian Osman788b9162020-02-07 10:36:46 -0500212 zPlaneParams.fZ = std::max(1.0f, 64 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500213 this->drawShadowedPath(canvas, fRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
214 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
Jim Van Verthbce74962017-01-25 09:39:46 -0500215
216 paint.setColor(SK_ColorYELLOW);
217 canvas->translate(-250, 110);
Brian Osman788b9162020-02-07 10:36:46 -0500218 zPlaneParams.fZ = std::max(1.0f, 8 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500219 this->drawShadowedPath(canvas, fFunkyRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
220 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
Jim Van Verthbce74962017-01-25 09:39:46 -0500221
222 paint.setColor(SK_ColorCYAN);
223 canvas->translate(250, 0);
Brian Osman788b9162020-02-07 10:36:46 -0500224 zPlaneParams.fZ = std::max(1.0f, 16 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500225 this->drawShadowedPath(canvas, fCubicPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
226 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500227
Jim Van Verth872da6b2018-04-10 11:24:11 -0400228 paint.setColor(SK_ColorWHITE);
229 canvas->translate(250, -180);
Brian Osman788b9162020-02-07 10:36:46 -0500230 zPlaneParams.fZ = std::max(1.0f, 8 + fZDelta);
Jim Van Verth872da6b2018-04-10 11:24:11 -0400231 this->drawShadowedPath(canvas, fStarPath, zPlaneParams, paint,
232 kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
233
234 paint.setColor(SK_ColorWHITE);
235 canvas->translate(150, 0);
Brian Osman788b9162020-02-07 10:36:46 -0500236 zPlaneParams.fZ = std::max(1.0f, 2 + fZDelta);
Jim Van Verth872da6b2018-04-10 11:24:11 -0400237 this->drawShadowedPath(canvas, fNotchPath, zPlaneParams, paint,
238 kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
239
240 paint.setColor(SK_ColorWHITE);
241 canvas->translate(200, 0);
Brian Osman788b9162020-02-07 10:36:46 -0500242 zPlaneParams.fZ = std::max(1.0f, 16 + fZDelta);
Jim Van Verth872da6b2018-04-10 11:24:11 -0400243 this->drawShadowedPath(canvas, fTabPath, zPlaneParams, paint,
244 kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
245
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500246 // circular reveal
247 SkPath tmpPath;
248 SkPath tmpClipPath;
249 tmpClipPath.addCircle(fAnimTranslate, 0, 60);
250 Op(fSquareRRectPath, tmpClipPath, kIntersect_SkPathOp, &tmpPath);
251
252 paint.setColor(SK_ColorMAGENTA);
Jim Van Verth872da6b2018-04-10 11:24:11 -0400253 canvas->translate(-725, 240);
Brian Osman788b9162020-02-07 10:36:46 -0500254 zPlaneParams.fZ = std::max(1.0f, 32 + fZDelta);
Jim Van Verthe308a122017-05-08 14:19:30 -0400255 this->drawShadowedPath(canvas, tmpPath, zPlaneParams, paint, .1f,
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500256 lightPos, kLightWidth, .5f);
257
Jim Van Verthf507c282018-05-11 10:48:20 -0400258 // path ops bug
259 SkPath tmpClipPathBug;
260 tmpClipPathBug.addCircle(88.0344925f, 0, 60);
261 Op(fSquareRRectPath, tmpClipPathBug, kIntersect_SkPathOp, &tmpPath);
262
263 canvas->translate(250, 0);
Brian Osman788b9162020-02-07 10:36:46 -0500264 zPlaneParams.fZ = std::max(1.0f, 32 + fZDelta);
Jim Van Verthf507c282018-05-11 10:48:20 -0400265 this->drawShadowedPath(canvas, tmpPath, zPlaneParams, paint, .1f,
266 lightPos, kLightWidth, .5f);
267
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500268 // perspective paths
269 SkPoint pivot = SkPoint::Make(fWideRectPath.getBounds().width()/2,
270 fWideRectPath.getBounds().height()/2);
Jim Van Verthda965502017-04-11 15:29:14 -0400271 SkPoint translate = SkPoint::Make(100, 450);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500272 paint.setColor(SK_ColorWHITE);
273 Sk3DView view;
274 view.save();
Jim Van Verthda965502017-04-11 15:29:14 -0400275 view.rotateX(fAnimAngle);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500276 SkMatrix persp;
277 view.getMatrix(&persp);
278 persp.preTranslate(-pivot.fX, -pivot.fY);
279 persp.postTranslate(pivot.fX + translate.fX, pivot.fY + translate.fY);
280 canvas->setMatrix(persp);
Jim Van Verthda965502017-04-11 15:29:14 -0400281 SkScalar radians = SkDegreesToRadians(fAnimAngle);
Jim Van Verthe308a122017-05-08 14:19:30 -0400282 zPlaneParams = SkPoint3::Make(0,
Jim Van Verth0b7645f2018-08-31 12:36:52 -0400283 SkScalarSin(radians),
Brian Osman788b9162020-02-07 10:36:46 -0500284 std::max(1.0f, 16 + fZDelta) - SkScalarSin(radians)*pivot.fY);
Jim Van Verthe308a122017-05-08 14:19:30 -0400285 this->drawShadowedPath(canvas, fWideRectPath, zPlaneParams, paint, .1f,
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500286 lightPos, kLightWidth, .5f);
287
288 pivot = SkPoint::Make(fWideOvalPath.getBounds().width() / 2,
289 fWideOvalPath.getBounds().height() / 2);
Jim Van Verthda965502017-04-11 15:29:14 -0400290 translate = SkPoint::Make(100, 600);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500291 view.restore();
Jim Van Verthe39bc9f2018-06-14 14:43:00 -0400292 view.save();
Jim Van Verthda965502017-04-11 15:29:14 -0400293 view.rotateY(fAnimAngle);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500294 view.getMatrix(&persp);
295 persp.preTranslate(-pivot.fX, -pivot.fY);
296 persp.postTranslate(pivot.fX + translate.fX, pivot.fY + translate.fY);
297 canvas->setMatrix(persp);
Jim Van Verthe308a122017-05-08 14:19:30 -0400298 zPlaneParams = SkPoint3::Make(-SkScalarSin(radians),
299 0,
Brian Osman788b9162020-02-07 10:36:46 -0500300 std::max(1.0f, 32 + fZDelta) + SkScalarSin(radians)*pivot.fX);
Jim Van Verthe308a122017-05-08 14:19:30 -0400301 this->drawShadowedPath(canvas, fWideOvalPath, zPlaneParams, paint, .1f,
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500302 lightPos, kLightWidth, .5f);
Jim Van Verthe39bc9f2018-06-14 14:43:00 -0400303
304 pivot = SkPoint::Make(fStarPath.getBounds().width() / 2,
305 fStarPath.getBounds().height() / 2);
306 translate = SkPoint::Make(700, 250);
307 view.restore();
308 view.rotateY(fAnimAngle);
309 view.getMatrix(&persp);
310 persp.preTranslate(-pivot.fX, -pivot.fY);
311 persp.postTranslate(pivot.fX + translate.fX, pivot.fY + translate.fY);
312 canvas->setMatrix(persp);
313 zPlaneParams = SkPoint3::Make(-SkScalarSin(radians),
314 0,
Brian Osman788b9162020-02-07 10:36:46 -0500315 std::max(1.0f, 8 + fZDelta) + SkScalarSin(radians)*pivot.fX);
Jim Van Verthe39bc9f2018-06-14 14:43:00 -0400316 this->drawShadowedPath(canvas, fStarPath, zPlaneParams, paint, .1f,
317 lightPos, kLightWidth, .5f);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500318 }
319
Hal Canary41248072019-07-11 16:32:53 -0400320 bool onAnimate(double nanos) override {
321 fAnimTranslate = TimeUtils::PingPong(1e-9 * nanos, 30, 0, 125, -125);
322 fAnimAngle = TimeUtils::PingPong(1e-9 * nanos, 15, 0, 0, 20);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500323 if (fDoAlphaAnimation) {
Hal Canary41248072019-07-11 16:32:53 -0400324 fAnimAlpha = TimeUtils::PingPong(1e-9 * nanos, 5, 0, 1, 0);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500325 }
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500326 return true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700327 }
328
jvanverthe1a3bc62016-08-12 10:40:38 -0700329private:
John Stiles7571f9e2020-09-02 22:42:33 -0400330 using INHERITED = Sample;
jvanverthe1a3bc62016-08-12 10:40:38 -0700331};
332
333//////////////////////////////////////////////////////////////////////////////
334
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400335DEF_SAMPLE( return new ShadowsView(); )