OLD | NEW |
(Empty) | |
| 1 /* |
| 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 |
| 20 const struct { |
| 21 SkXfermode::Mode fMode; |
| 22 const char* fName; |
| 23 } gModes[] = { |
| 24 { SkXfermode::kSrcOver_Mode, "src-over" }, |
| 25 { SkXfermode::kSrc_Mode, "src" }, |
| 26 { SkXfermode::kSrcIn_Mode, "src-in" }, |
| 27 { SkXfermode::kSrcOut_Mode, "src-out" }, |
| 28 { SkXfermode::kSrcATop_Mode, "src-atop" }, |
| 29 { SkXfermode::kDstOver_Mode, "dst-over" }, |
| 30 { SkXfermode::kDstIn_Mode, "dst-in" }, |
| 31 { SkXfermode::kDstOut_Mode, "dst-out" }, |
| 32 { SkXfermode::kDstATop_Mode, "dst-atop" }, |
| 33 }; |
| 34 const int N_Modes = SK_ARRAY_COUNT(gModes); |
| 35 |
| 36 class HasEventWig : public SkView { |
| 37 public: |
| 38 void postWidgetEvent() { |
| 39 SkEvent evt; |
| 40 this->onPrepareWidEvent(&evt); |
| 41 this->postToListeners(evt, 0); |
| 42 } |
| 43 |
| 44 protected: |
| 45 virtual void onPrepareWidEvent(SkEvent*) {} |
| 46 }; |
| 47 |
| 48 static SkRandom gRand; |
| 49 |
| 50 class PushButtonWig : public HasEventWig { |
| 51 SkString fLabel; |
| 52 SkColor fColor; |
| 53 uint32_t fFast32; |
| 54 |
| 55 public: |
| 56 PushButtonWig(const char label[], uint32_t fast) : fLabel(label) { |
| 57 fColor = (gRand.nextU() & 0x7F7F7F7F) | SkColorSetARGB(0xFF, 0, 0, 0x80)
; |
| 58 fFast32 = fast; |
| 59 } |
| 60 |
| 61 protected: |
| 62 void onPrepareWidEvent(SkEvent* evt) override { |
| 63 evt->setType("push-button"); |
| 64 evt->setFast32(fFast32); |
| 65 evt->setString("label", fLabel.c_str()); |
| 66 } |
| 67 |
| 68 // bool onEvent(const SkEvent&) override; |
| 69 void onDraw(SkCanvas* canvas) override { |
| 70 SkRect r; |
| 71 this->getLocalBounds(&r); |
| 72 SkPaint paint; |
| 73 paint.setAntiAlias(true); |
| 74 paint.setColor(fColor); |
| 75 canvas->drawRoundRect(r, 8, 8, paint); |
| 76 |
| 77 paint.setColor(0xFFFFFFFF); |
| 78 paint.setTextSize(16); |
| 79 paint.setTextAlign(SkPaint::kCenter_Align); |
| 80 paint.setLCDRenderText(true); |
| 81 canvas->drawText(fLabel.c_str(), fLabel.size(), r.centerX(), r.fTop + 0.
68f * r.height(), paint); |
| 82 } |
| 83 |
| 84 Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override { |
| 85 return new Click(this); |
| 86 } |
| 87 |
| 88 bool onClick(Click* click) override { |
| 89 SkRect target = SkRect::MakeXYWH(click->fCurr.x() - 1, click->fCurr.y()
- 1, 3, 3); |
| 90 SkRect r; |
| 91 this->getLocalBounds(&r); |
| 92 if (r.intersects(target)) { |
| 93 fColor = SkColorSetA(fColor, 0x99); |
| 94 } else { |
| 95 fColor = SkColorSetA(fColor, 0xFF); |
| 96 } |
| 97 this->inval(nullptr); |
| 98 |
| 99 if (click->fState == SkView::Click::kUp_State) { |
| 100 this->postWidgetEvent(); |
| 101 } |
| 102 return true; |
| 103 } |
| 104 |
| 105 private: |
| 106 typedef HasEventWig INHERITED; |
| 107 }; |
| 108 |
| 109 |
| 110 class ModeDrawable : public SkDrawable { |
| 111 public: |
| 112 ModeDrawable() : fMode(SkXfermode::kSrcOver_Mode), fLoc(SkPoint::Make(0, 0))
{} |
| 113 |
| 114 SkXfermode::Mode fMode; |
| 115 SkPoint fLoc; |
| 116 |
| 117 bool hitTest(SkScalar x, SkScalar y) { |
| 118 SkRect target = SkRect::MakeXYWH(x - fLoc.x() - 1, y - fLoc.y() - 1, 3,
3); |
| 119 return this->getBounds().intersects(target); |
| 120 } |
| 121 }; |
| 122 |
| 123 class CircDrawable : public ModeDrawable { |
| 124 SkPaint fPaint; |
| 125 SkRect fBounds; |
| 126 |
| 127 public: |
| 128 CircDrawable(SkScalar size, SkColor c) { |
| 129 const SkColor colors[] = { 0, c }; |
| 130 SkAutoTUnref<SkShader> shader(SkGradientShader::CreateRadial(SkPoint::Ma
ke(size/2, size/2), size/2, |
| 131 colors, nul
lptr, 2, |
| 132 SkShader::k
Clamp_TileMode)); |
| 133 fPaint.setShader(shader); |
| 134 fBounds = SkRect::MakeWH(size, size); |
| 135 } |
| 136 |
| 137 protected: |
| 138 SkRect onGetBounds() override { |
| 139 return fBounds; |
| 140 } |
| 141 |
| 142 void onDraw(SkCanvas* canvas) override { |
| 143 fPaint.setXfermodeMode(fMode); |
| 144 canvas->save(); |
| 145 canvas->translate(fLoc.x(), fLoc.y()); |
| 146 canvas->drawOval(fBounds, fPaint); |
| 147 canvas->restore(); |
| 148 } |
| 149 }; |
| 150 |
| 151 class XferDemo : public SampleView { |
| 152 enum { |
| 153 N = 4 |
| 154 }; |
| 155 |
| 156 SkRect fModeRect[N_Modes]; |
| 157 SkAutoTUnref<CircDrawable> fDrs[N]; |
| 158 CircDrawable* fSelected; |
| 159 |
| 160 void addButtons() { |
| 161 SkScalar x = 10; |
| 162 SkScalar y = 10; |
| 163 for (int i = 0; i < N_Modes; ++i) { |
| 164 SkAutoTUnref<SkView> v(new PushButtonWig(gModes[i].fName, gModes[i].
fMode)); |
| 165 v->setSize(70, 25); |
| 166 v->setLoc(x, y); |
| 167 v->setVisibleP(true); |
| 168 v->setEnabledP(true); |
| 169 v->addListenerID(this->getSinkID()); |
| 170 this->attachChildToFront(v); |
| 171 fModeRect[i] = SkRect::MakeXYWH(x, y + 28, 70, 2); |
| 172 x += 80; |
| 173 } |
| 174 } |
| 175 |
| 176 public: |
| 177 XferDemo() { |
| 178 const SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_
ColorBLACK }; |
| 179 for (int i = 0; i < N; ++i) { |
| 180 fDrs[i].reset(new CircDrawable(200, colors[i])); |
| 181 fDrs[i]->fLoc.set(100.f + i * 100, 100.f + i * 100); |
| 182 fDrs[i]->fMode = SkXfermode::kSrcOver_Mode; |
| 183 } |
| 184 fSelected = nullptr; |
| 185 |
| 186 this->addButtons(); |
| 187 } |
| 188 |
| 189 protected: |
| 190 bool onEvent(const SkEvent& evt) override { |
| 191 if (evt.isType("push-button")) { |
| 192 if (fSelected) { |
| 193 fSelected->fMode = (SkXfermode::Mode)evt.getFast32(); |
| 194 this->inval(nullptr); |
| 195 } |
| 196 return true; |
| 197 } |
| 198 return this->INHERITED::onEvent(evt); |
| 199 } |
| 200 |
| 201 bool onQuery(SkEvent* evt) override { |
| 202 if (SampleCode::TitleQ(*evt)) { |
| 203 SampleCode::TitleR(evt, "XferDemo"); |
| 204 return true; |
| 205 } |
| 206 return this->INHERITED::onQuery(evt); |
| 207 } |
| 208 |
| 209 void onDrawContent(SkCanvas* canvas) override { |
| 210 SkPaint paint; |
| 211 if (fSelected) { |
| 212 for (int i = 0; i < N_Modes; ++i) { |
| 213 if (fSelected->fMode == gModes[i].fMode) { |
| 214 canvas->drawRect(fModeRect[i], paint); |
| 215 break; |
| 216 } |
| 217 } |
| 218 } |
| 219 |
| 220 canvas->saveLayer(nullptr, nullptr); |
| 221 for (int i = 0; i < N; ++i) { |
| 222 fDrs[i]->draw(canvas); |
| 223 } |
| 224 canvas->restore(); |
| 225 } |
| 226 |
| 227 SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override
{ |
| 228 fSelected = nullptr; |
| 229 for (int i = N - 1; i >= 0; --i) { |
| 230 if (fDrs[i]->hitTest(x, y)) { |
| 231 fSelected = fDrs[i]; |
| 232 break; |
| 233 } |
| 234 } |
| 235 this->inval(nullptr); |
| 236 return fSelected ? new Click(this) : nullptr; |
| 237 } |
| 238 |
| 239 bool onClick(Click* click) override { |
| 240 fSelected->fLoc.fX += click->fCurr.fX - click->fPrev.fX; |
| 241 fSelected->fLoc.fY += click->fCurr.fY - click->fPrev.fY; |
| 242 this->inval(nullptr); |
| 243 return true; |
| 244 } |
| 245 |
| 246 private: |
| 247 typedef SampleView INHERITED; |
| 248 }; |
| 249 |
| 250 ////////////////////////////////////////////////////////////////////////////// |
| 251 |
| 252 DEF_SAMPLE( return new XferDemo; ) |
OLD | NEW |