mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2012 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 "SkView.h" |
| 10 | #include "SkCanvas.h" |
| 11 | #include "SkRandom.h" |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 12 | #include "SkRRect.h" |
| 13 | #include "SkColorPriv.h" |
caryclark | feff7d2 | 2014-10-09 05:36:03 -0700 | [diff] [blame] | 14 | #include "SkStrokerPriv.h" |
mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 15 | |
| 16 | static void rotateAbout(SkCanvas* canvas, SkScalar degrees, |
| 17 | SkScalar cx, SkScalar cy) { |
| 18 | canvas->translate(cx, cy); |
| 19 | canvas->rotate(degrees); |
| 20 | canvas->translate(-cx, -cy); |
| 21 | } |
| 22 | |
| 23 | class RotateCirclesView : public SampleView { |
| 24 | public: |
| 25 | RotateCirclesView() { |
| 26 | this->setBGColor(SK_ColorLTGRAY); |
skia.committer@gmail.com | 15ed90f | 2012-12-23 02:01:31 +0000 | [diff] [blame] | 27 | |
mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 28 | fAngle = 0; |
| 29 | } |
| 30 | |
| 31 | protected: |
| 32 | // overrides from SkEventSink |
| 33 | virtual bool onQuery(SkEvent* evt) { |
| 34 | if (SampleCode::TitleQ(*evt)) { |
| 35 | SampleCode::TitleR(evt, "RotateCircles"); |
| 36 | return true; |
| 37 | } |
| 38 | return this->INHERITED::onQuery(evt); |
| 39 | } |
| 40 | |
| 41 | virtual void onDrawContent(SkCanvas* canvas) { |
commit-bot@chromium.org | e0e7cfe | 2013-09-09 20:09:12 +0000 | [diff] [blame] | 42 | SkRandom rand; |
mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 43 | SkPaint paint; |
| 44 | paint.setAntiAlias(true); |
| 45 | paint.setStrokeWidth(20); |
| 46 | |
| 47 | SkScalar cx = 240; |
| 48 | SkScalar cy = 240; |
| 49 | SkScalar DX = 240 * 2; |
| 50 | SkColor color = 0; |
| 51 | |
| 52 | float scale = 1; |
| 53 | float sign = 0.3f; |
| 54 | for (SkScalar rad = 200; rad >= 20; rad -= 15) { |
| 55 | sign = -sign; |
| 56 | scale += 0.2f; |
| 57 | |
| 58 | paint.setColor(rand.nextU()); |
| 59 | paint.setAlpha(0xFF); |
| 60 | color = ~color; |
skia.committer@gmail.com | 15ed90f | 2012-12-23 02:01:31 +0000 | [diff] [blame] | 61 | |
mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 62 | paint.setStyle(SkPaint::kFill_Style); |
| 63 | |
| 64 | canvas->save(); |
| 65 | rotateAbout(canvas, fAngle * scale * sign, cx, cy); |
| 66 | canvas->drawCircle(cx, cy, rad, paint); |
| 67 | canvas->restore(); |
| 68 | |
| 69 | paint.setStyle(SkPaint::kStroke_Style); |
| 70 | paint.setStrokeWidth(rad*2); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 71 | |
mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 72 | canvas->save(); |
| 73 | rotateAbout(canvas, fAngle * scale * sign, cx + DX, cy); |
| 74 | canvas->drawCircle(cx + DX, cy, 10, paint); |
| 75 | canvas->restore(); |
skia.committer@gmail.com | 15ed90f | 2012-12-23 02:01:31 +0000 | [diff] [blame] | 76 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 77 | canvas->save(); |
| 78 | rotateAbout(canvas, fAngle * scale * sign, cx + DX, cy + DX); |
| 79 | canvas->drawCircle(cx + DX, cy + DX, 10, paint); |
| 80 | canvas->restore(); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 81 | |
mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 82 | } |
skia.committer@gmail.com | 15ed90f | 2012-12-23 02:01:31 +0000 | [diff] [blame] | 83 | |
mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 84 | fAngle = (fAngle + 1) % 360; |
| 85 | this->inval(NULL); |
| 86 | } |
| 87 | |
| 88 | private: |
| 89 | int fAngle; |
| 90 | typedef SkView INHERITED; |
| 91 | }; |
| 92 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 93 | class TestCirclesView : public SampleView { |
| 94 | public: |
| 95 | TestCirclesView() { |
| 96 | } |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 97 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 98 | protected: |
| 99 | virtual bool onQuery(SkEvent* evt) SK_OVERRIDE { |
| 100 | if (SampleCode::TitleQ(*evt)) { |
| 101 | SampleCode::TitleR(evt, "RotateCircles2"); |
| 102 | return true; |
| 103 | } |
| 104 | return this->INHERITED::onQuery(evt); |
| 105 | } |
| 106 | |
| 107 | void draw_real_circle(SkCanvas* canvas, SkScalar radius) { |
| 108 | int w = SkScalarCeilToInt(radius * 2); |
| 109 | int h = w; |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 110 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 111 | SkBitmap bm; |
commit-bot@chromium.org | a8c1831 | 2014-02-17 02:55:57 +0000 | [diff] [blame] | 112 | bm.allocN32Pixels(w, h); |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 113 | bm.eraseColor(0); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 114 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 115 | SkAutoLockPixels alp(bm); |
| 116 | |
| 117 | SkScalar cx = radius; |
| 118 | SkScalar cy = radius; |
| 119 | for (int y = 0; y < h; y += 1) { |
| 120 | for (int x = 0; x < w; x += 1) { |
| 121 | float d = sqrtf((x - cx)*(x - cx) + (y - cy)*(y - cy)); |
| 122 | if (d <= radius) { |
| 123 | *bm.getAddr32(x, y) = SkPackARGB32(0xFF, 0, 0, 0); |
| 124 | } |
| 125 | } |
| 126 | } |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 127 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 128 | canvas->drawBitmap(bm, 0, 0, NULL); |
| 129 | } |
| 130 | |
| 131 | virtual void onDrawContent(SkCanvas* canvas) { |
| 132 | SkScalar radius = 256; |
| 133 | canvas->translate(10, 10); |
| 134 | |
| 135 | draw_real_circle(canvas, radius); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 136 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 137 | SkPaint paint; |
| 138 | paint.setAntiAlias(true); |
| 139 | |
| 140 | paint.setColor(0x80FF0000); |
| 141 | canvas->drawCircle(radius, radius, radius, paint); |
| 142 | |
| 143 | paint.setStyle(SkPaint::kStroke_Style); |
| 144 | paint.setStrokeWidth(radius); |
| 145 | paint.setColor(0x8000FF00); |
| 146 | canvas->drawCircle(radius, radius, radius/2, paint); |
| 147 | } |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 148 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 149 | private: |
| 150 | typedef SkView INHERITED; |
| 151 | }; |
| 152 | |
| 153 | static bool hittest(const SkPoint& target, SkScalar x, SkScalar y) { |
| 154 | const SkScalar TOL = 7; |
| 155 | return SkPoint::Distance(target, SkPoint::Make(x, y)) <= TOL; |
| 156 | } |
| 157 | |
| 158 | static int getOnCurvePoints(const SkPath& path, SkPoint storage[]) { |
| 159 | SkPath::RawIter iter(path); |
| 160 | SkPoint pts[4]; |
| 161 | SkPath::Verb verb; |
| 162 | |
| 163 | int count = 0; |
| 164 | while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { |
| 165 | switch (verb) { |
| 166 | case SkPath::kMove_Verb: |
| 167 | case SkPath::kLine_Verb: |
| 168 | case SkPath::kQuad_Verb: |
| 169 | case SkPath::kCubic_Verb: |
| 170 | storage[count++] = pts[0]; |
| 171 | break; |
| 172 | default: |
| 173 | break; |
| 174 | } |
| 175 | } |
| 176 | return count; |
| 177 | } |
| 178 | |
| 179 | #include "SkPathMeasure.h" |
| 180 | |
caryclark | feff7d2 | 2014-10-09 05:36:03 -0700 | [diff] [blame] | 181 | struct StrokeTypeButton { |
| 182 | SkRect fBounds; |
| 183 | char fLabel; |
| 184 | bool fEnabled; |
| 185 | }; |
| 186 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 187 | class TestStrokeView : public SampleView { |
| 188 | enum { |
| 189 | SKELETON_COLOR = 0xFF0000FF, |
| 190 | WIREFRAME_COLOR = 0x80FF0000 |
| 191 | }; |
| 192 | |
| 193 | enum { |
| 194 | kCount = 9 |
| 195 | }; |
| 196 | SkPoint fPts[kCount]; |
caryclark | feff7d2 | 2014-10-09 05:36:03 -0700 | [diff] [blame] | 197 | SkRect fErrorControl; |
| 198 | SkRect fWidthControl; |
| 199 | StrokeTypeButton fCubicButton; |
| 200 | StrokeTypeButton fQuadButton; |
| 201 | StrokeTypeButton fRRectButton; |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 202 | SkScalar fWidth, fDWidth; |
caryclark | feff7d2 | 2014-10-09 05:36:03 -0700 | [diff] [blame] | 203 | bool fAnimate; |
| 204 | #if QUAD_STROKE_APPROXIMATION && defined(SK_DEBUG) |
| 205 | #define kStrokerErrorMin 0.001f |
| 206 | #define kStrokerErrorMax 5 |
| 207 | #endif |
| 208 | #define kWidthMin 1 |
| 209 | #define kWidthMax 100 |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 210 | public: |
| 211 | TestStrokeView() { |
| 212 | this->setBGColor(SK_ColorLTGRAY); |
| 213 | |
| 214 | fPts[0].set(50, 200); |
| 215 | fPts[1].set(50, 100); |
| 216 | fPts[2].set(150, 50); |
| 217 | fPts[3].set(300, 50); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 218 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 219 | fPts[4].set(350, 200); |
| 220 | fPts[5].set(350, 100); |
| 221 | fPts[6].set(450, 50); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 222 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 223 | fPts[7].set(200, 200); |
| 224 | fPts[8].set(400, 400); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 225 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 226 | fWidth = 50; |
| 227 | fDWidth = 0.25f; |
caryclark | feff7d2 | 2014-10-09 05:36:03 -0700 | [diff] [blame] | 228 | |
| 229 | fCubicButton.fLabel = 'C'; |
| 230 | fCubicButton.fEnabled = true; |
| 231 | fQuadButton.fLabel = 'Q'; |
| 232 | fQuadButton.fEnabled = true; |
| 233 | fRRectButton.fLabel = 'R'; |
| 234 | fRRectButton.fEnabled = true; |
| 235 | fAnimate = true; |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 236 | } |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 237 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 238 | protected: |
| 239 | virtual bool onQuery(SkEvent* evt) SK_OVERRIDE { |
| 240 | if (SampleCode::TitleQ(*evt)) { |
| 241 | SampleCode::TitleR(evt, "RotateCircles3"); |
| 242 | return true; |
| 243 | } |
| 244 | return this->INHERITED::onQuery(evt); |
| 245 | } |
| 246 | |
caryclark | feff7d2 | 2014-10-09 05:36:03 -0700 | [diff] [blame] | 247 | virtual void onSizeChange() { |
| 248 | fErrorControl.setXYWH(this->width() - 100, 30, 30, 400); |
| 249 | fWidthControl.setXYWH(this->width() - 50, 30, 30, 400); |
| 250 | fCubicButton.fBounds.setXYWH(this->width() - 50, 450, 30, 30); |
| 251 | fQuadButton.fBounds.setXYWH(this->width() - 50, 500, 30, 30); |
| 252 | fRRectButton.fBounds.setXYWH(this->width() - 50, 550, 30, 30); |
| 253 | this->INHERITED::onSizeChange(); |
| 254 | } |
| 255 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 256 | void draw_points(SkCanvas* canvas, const SkPath& path, SkColor color, |
| 257 | bool show_lines) { |
| 258 | SkPaint paint; |
| 259 | paint.setColor(color); |
| 260 | paint.setAlpha(0x80); |
caryclark | feff7d2 | 2014-10-09 05:36:03 -0700 | [diff] [blame] | 261 | paint.setAntiAlias(true); |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 262 | int n = path.countPoints(); |
| 263 | SkAutoSTArray<32, SkPoint> pts(n); |
| 264 | if (show_lines) { |
| 265 | path.getPoints(pts.get(), n); |
| 266 | canvas->drawPoints(SkCanvas::kPolygon_PointMode, n, pts.get(), paint); |
| 267 | } else { |
| 268 | n = getOnCurvePoints(path, pts.get()); |
| 269 | } |
| 270 | paint.setStrokeWidth(5); |
| 271 | canvas->drawPoints(SkCanvas::kPoints_PointMode, n, pts.get(), paint); |
| 272 | } |
| 273 | |
| 274 | void draw_ribs(SkCanvas* canvas, const SkPath& path, SkScalar width, |
| 275 | SkColor color) { |
| 276 | const SkScalar radius = width / 2; |
| 277 | |
| 278 | SkPathMeasure meas(path, false); |
| 279 | SkScalar total = meas.getLength(); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 280 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 281 | SkScalar delta = 8; |
| 282 | SkPaint paint; |
| 283 | paint.setColor(color); |
| 284 | |
| 285 | SkPoint pos, tan; |
| 286 | for (SkScalar dist = 0; dist <= total; dist += delta) { |
reed@google.com | 140d728 | 2013-01-07 20:25:04 +0000 | [diff] [blame] | 287 | if (meas.getPosTan(dist, &pos, &tan)) { |
| 288 | tan.scale(radius); |
| 289 | tan.rotateCCW(); |
| 290 | canvas->drawLine(pos.x() + tan.x(), pos.y() + tan.y(), |
| 291 | pos.x() - tan.x(), pos.y() - tan.y(), paint); |
| 292 | } |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 293 | } |
| 294 | } |
| 295 | |
| 296 | void draw_stroke(SkCanvas* canvas, const SkPath& path, SkScalar width) { |
| 297 | SkPaint paint; |
| 298 | paint.setAntiAlias(true); |
| 299 | paint.setStyle(SkPaint::kStroke_Style); |
| 300 | |
| 301 | paint.setColor(SKELETON_COLOR); |
| 302 | canvas->drawPath(path, paint); |
| 303 | draw_points(canvas, path, SKELETON_COLOR, true); |
| 304 | |
| 305 | draw_ribs(canvas, path, width, 0xFF00FF00); |
| 306 | |
| 307 | SkPath fill; |
| 308 | |
| 309 | SkPaint p; |
| 310 | p.setStyle(SkPaint::kStroke_Style); |
| 311 | p.setStrokeWidth(width); |
| 312 | p.getFillPath(path, &fill); |
| 313 | |
| 314 | paint.setColor(WIREFRAME_COLOR); |
| 315 | canvas->drawPath(fill, paint); |
| 316 | draw_points(canvas, fill, WIREFRAME_COLOR, false); |
| 317 | } |
| 318 | |
caryclark | feff7d2 | 2014-10-09 05:36:03 -0700 | [diff] [blame] | 319 | void draw_button(SkCanvas* canvas, const StrokeTypeButton& button) { |
| 320 | SkPaint paint; |
| 321 | paint.setAntiAlias(true); |
| 322 | paint.setStyle(SkPaint::kStroke_Style); |
| 323 | paint.setColor(button.fEnabled ? 0xFF3F0000 : 0x6F3F0000); |
| 324 | canvas->drawRect(button.fBounds, paint); |
| 325 | paint.setTextSize(25.0f); |
| 326 | paint.setColor(button.fEnabled ? 0xFF3F0000 : 0x6F3F0000); |
| 327 | paint.setTextAlign(SkPaint::kCenter_Align); |
| 328 | paint.setStyle(SkPaint::kFill_Style); |
| 329 | canvas->drawText(&button.fLabel, 1, button.fBounds.centerX(), button.fBounds.fBottom - 5, |
| 330 | paint); |
| 331 | } |
| 332 | |
| 333 | void draw_control(SkCanvas* canvas, const SkRect& bounds, SkScalar value, |
| 334 | SkScalar min, SkScalar max, const char* name) { |
| 335 | SkPaint paint; |
| 336 | paint.setAntiAlias(true); |
| 337 | paint.setStyle(SkPaint::kStroke_Style); |
| 338 | canvas->drawRect(bounds, paint); |
| 339 | SkScalar scale = max - min; |
| 340 | SkScalar yPos = bounds.fTop + (value - min) * bounds.height() / scale; |
| 341 | paint.setColor(0xFFFF0000); |
| 342 | canvas->drawLine(bounds.fLeft - 5, yPos, bounds.fRight + 5, yPos, paint); |
| 343 | SkString label; |
| 344 | label.printf("%0.3g", value); |
| 345 | paint.setColor(0xFF000000); |
| 346 | paint.setTextSize(11.0f); |
| 347 | paint.setStyle(SkPaint::kFill_Style); |
| 348 | canvas->drawText(label.c_str(), label.size(), bounds.fLeft + 5, yPos - 5, paint); |
| 349 | paint.setTextSize(13.0f); |
| 350 | canvas->drawText(name, strlen(name), bounds.fLeft, bounds.bottom() + 11, paint); |
| 351 | } |
| 352 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 353 | virtual void onDrawContent(SkCanvas* canvas) { |
| 354 | SkPath path; |
| 355 | SkScalar width = fWidth; |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 356 | |
caryclark | feff7d2 | 2014-10-09 05:36:03 -0700 | [diff] [blame] | 357 | if (fCubicButton.fEnabled) { |
| 358 | path.moveTo(fPts[0]); |
| 359 | path.cubicTo(fPts[1], fPts[2], fPts[3]); |
| 360 | draw_stroke(canvas, path, width); |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 361 | } |
caryclark | feff7d2 | 2014-10-09 05:36:03 -0700 | [diff] [blame] | 362 | |
| 363 | if (fQuadButton.fEnabled) { |
| 364 | path.reset(); |
| 365 | path.moveTo(fPts[4]); |
| 366 | path.quadTo(fPts[5], fPts[6]); |
| 367 | draw_stroke(canvas, path, width); |
| 368 | } |
| 369 | |
| 370 | if (fRRectButton.fEnabled) { |
| 371 | SkScalar rad = 32; |
| 372 | SkRect r; |
| 373 | r.set(&fPts[7], 2); |
| 374 | path.reset(); |
| 375 | SkRRect rr; |
| 376 | rr.setRectXY(r, rad, rad); |
| 377 | path.addRRect(rr); |
| 378 | draw_stroke(canvas, path, width); |
| 379 | |
| 380 | path.reset(); |
| 381 | SkRRect rr2; |
| 382 | rr.inset(width/2, width/2, &rr2); |
| 383 | path.addRRect(rr2, SkPath::kCCW_Direction); |
| 384 | rr.inset(-width/2, -width/2, &rr2); |
| 385 | path.addRRect(rr2, SkPath::kCW_Direction); |
| 386 | SkPaint paint; |
| 387 | paint.setAntiAlias(true); |
| 388 | paint.setColor(0x40FF8844); |
| 389 | canvas->drawPath(path, paint); |
| 390 | } |
| 391 | |
| 392 | if (fAnimate) { |
| 393 | fWidth += fDWidth; |
| 394 | if (fDWidth > 0 && fWidth > kWidthMax) { |
| 395 | fDWidth = -fDWidth; |
| 396 | } else if (fDWidth < 0 && fWidth < kWidthMin) { |
| 397 | fDWidth = -fDWidth; |
| 398 | } |
| 399 | } |
| 400 | #if QUAD_STROKE_APPROXIMATION && defined(SK_DEBUG) |
| 401 | draw_control(canvas, fErrorControl, gDebugStrokerError, kStrokerErrorMin, kStrokerErrorMax, |
| 402 | "error"); |
| 403 | #endif |
| 404 | draw_control(canvas, fWidthControl, fWidth, kWidthMin, kWidthMax, "width"); |
| 405 | draw_button(canvas, fQuadButton); |
| 406 | draw_button(canvas, fCubicButton); |
| 407 | draw_button(canvas, fRRectButton); |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 408 | this->inval(NULL); |
| 409 | } |
| 410 | |
| 411 | class MyClick : public Click { |
| 412 | public: |
| 413 | int fIndex; |
| 414 | MyClick(SkView* target, int index) : Click(target), fIndex(index) {} |
| 415 | }; |
| 416 | |
reed@google.com | 4d5c26d | 2013-01-08 16:17:50 +0000 | [diff] [blame] | 417 | virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, |
| 418 | unsigned modi) SK_OVERRIDE { |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 419 | for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); ++i) { |
| 420 | if (hittest(fPts[i], x, y)) { |
reed@google.com | 7fa2a65 | 2014-01-27 13:42:58 +0000 | [diff] [blame] | 421 | return new MyClick(this, (int)i); |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 422 | } |
| 423 | } |
caryclark | feff7d2 | 2014-10-09 05:36:03 -0700 | [diff] [blame] | 424 | const SkRect& rectPt = SkRect::MakeXYWH(x, y, 1, 1); |
| 425 | #if QUAD_STROKE_APPROXIMATION && defined(SK_DEBUG) |
| 426 | if (fErrorControl.contains(rectPt)) { |
| 427 | return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 1); |
| 428 | } |
| 429 | #endif |
| 430 | if (fWidthControl.contains(rectPt)) { |
| 431 | return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 3); |
| 432 | } |
| 433 | if (fCubicButton.fBounds.contains(rectPt)) { |
| 434 | fCubicButton.fEnabled ^= true; |
| 435 | return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 4); |
| 436 | } |
| 437 | if (fQuadButton.fBounds.contains(rectPt)) { |
| 438 | fQuadButton.fEnabled ^= true; |
| 439 | return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 5); |
| 440 | } |
| 441 | if (fRRectButton.fBounds.contains(rectPt)) { |
| 442 | fRRectButton.fEnabled ^= true; |
| 443 | return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 6); |
| 444 | } |
reed@google.com | 4d5c26d | 2013-01-08 16:17:50 +0000 | [diff] [blame] | 445 | return this->INHERITED::onFindClickHandler(x, y, modi); |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 446 | } |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 447 | |
caryclark | feff7d2 | 2014-10-09 05:36:03 -0700 | [diff] [blame] | 448 | static SkScalar MapScreenYtoValue(int y, const SkRect& control, SkScalar min, |
| 449 | SkScalar max) { |
| 450 | return (SkIntToScalar(y) - control.fTop) / control.height() * (max - min) + min; |
| 451 | } |
| 452 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 453 | virtual bool onClick(Click* click) { |
| 454 | int index = ((MyClick*)click)->fIndex; |
caryclark | feff7d2 | 2014-10-09 05:36:03 -0700 | [diff] [blame] | 455 | if (index < (int) SK_ARRAY_COUNT(fPts)) { |
| 456 | fPts[index].offset(SkIntToScalar(click->fICurr.fX - click->fIPrev.fX), |
| 457 | SkIntToScalar(click->fICurr.fY - click->fIPrev.fY)); |
| 458 | this->inval(NULL); |
| 459 | } |
| 460 | #if QUAD_STROKE_APPROXIMATION && defined(SK_DEBUG) |
| 461 | else if (index == (int) SK_ARRAY_COUNT(fPts) + 1) { |
| 462 | gDebugStrokerError = MapScreenYtoValue(click->fICurr.fY, fErrorControl, |
| 463 | kStrokerErrorMin, kStrokerErrorMax); |
| 464 | gDebugStrokerErrorSet = true; |
| 465 | } |
| 466 | #endif |
| 467 | else if (index == (int) SK_ARRAY_COUNT(fPts) + 3) { |
| 468 | fWidth = MapScreenYtoValue(click->fICurr.fY, fWidthControl, kWidthMin, kWidthMax); |
| 469 | fAnimate = fWidth <= kWidthMin; |
| 470 | } |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 471 | return true; |
| 472 | } |
| 473 | |
| 474 | private: |
| 475 | typedef SkView INHERITED; |
| 476 | }; |
| 477 | |
| 478 | /////////////////////////////////////////////////////////////////////////////// |
| 479 | |
mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 480 | static SkView* F0() { return new RotateCirclesView; } |
| 481 | static SkViewRegister gR0(F0); |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 482 | static SkView* F1() { return new TestCirclesView; } |
| 483 | static SkViewRegister gR1(F1); |
| 484 | static SkView* F2() { return new TestStrokeView; } |
| 485 | static SkViewRegister gR2(F2); |