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