1 /* 2 * Copyright 2019 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 "include/core/SkCanvas.h" 9 #include "include/core/SkFont.h" 10 #include "include/core/SkFontMetrics.h" 11 #include "include/core/SkPath.h" 12 #include "samplecode/Sample.h" 13 14 #include "modules/sksg/include/SkSGDraw.h" 15 #include "modules/sksg/include/SkSGGroup.h" 16 #include "modules/sksg/include/SkSGPaint.h" 17 #include "modules/sksg/include/SkSGRect.h" 18 #include "modules/sksg/include/SkSGScene.h" 19 20 struct PerNodeInfo { 21 // key 22 sksg::Draw* fDraw; 23 24 // value(s) 25 sksg::GeometryNode* fGeo; 26 sksg::PaintNode* fPaint; 27 }; 28 29 class SampleSG : public Sample { 30 SkTDArray<PerNodeInfo> fSideCar; 31 sk_sp<sksg::Group> fGroup; 32 std::unique_ptr<sksg::Scene> fScene; 33 findInfo(sksg::Draw * key)34 PerNodeInfo* findInfo(sksg::Draw* key) { 35 for (int i = 0; i < fSideCar.count(); ++i) { 36 if (fSideCar[i].fDraw == key) { 37 return &fSideCar[i]; 38 } 39 } 40 return nullptr; 41 } 42 appendNode(sk_sp<sksg::Draw> d,sk_sp<sksg::GeometryNode> g,sk_sp<sksg::PaintNode> p)43 void appendNode(sk_sp<sksg::Draw> d, sk_sp<sksg::GeometryNode> g, sk_sp<sksg::PaintNode> p) { 44 fGroup->addChild(d); 45 auto sc = fSideCar.append(); 46 sc->fDraw = d.get(); 47 sc->fGeo = g.get(); 48 sc->fPaint = p.get(); 49 } 50 51 public: SampleSG()52 SampleSG() { 53 fGroup = sksg::Group::Make(); 54 55 fScene = sksg::Scene::Make(fGroup); 56 57 auto r = sksg::Rect::Make({20, 20, 400, 300}); 58 auto p = sksg::Color::Make(SK_ColorRED); 59 auto d = sksg::Draw::Make(r, p); 60 this->appendNode(d, r, p); 61 62 r = sksg::Rect::Make({60, 70, 300, 400}); 63 p = sksg::Color::Make(SK_ColorBLUE); 64 d = sksg::Draw::Make(r, p); 65 this->appendNode(d, r, p); 66 } 67 68 protected: name()69 SkString name() override { return SkString("SceneGraph"); } 70 onDrawContent(SkCanvas * canvas)71 void onDrawContent(SkCanvas* canvas) override { 72 fScene->render(canvas); 73 } 74 onFindClickHandler(SkScalar x,SkScalar y,skui::ModifierKey modi)75 Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override { 76 if (auto node = fScene->nodeAt({x, y})) { 77 Click* click = new Click(); 78 click->fMeta.setPtr("node", (void*)node); 79 return click; 80 } 81 return nullptr; 82 } 83 onClick(Click * click)84 bool onClick(Click* click) override { 85 sksg::Draw* node = nullptr; 86 if (click->fMeta.findPtr("node", (void**)&node)) { 87 if (auto info = this->findInfo(node)) { 88 auto geo = info->fGeo; 89 sksg::Rect* r = (sksg::Rect*)geo; 90 SkScalar dx = click->fCurr.fX - click->fPrev.fX; 91 SkScalar dy = click->fCurr.fY - click->fPrev.fY; 92 r->setL(r->getL() + dx); 93 r->setR(r->getR() + dx); 94 r->setT(r->getT() + dy); 95 r->setB(r->getB() + dy); 96 } 97 return true; 98 } 99 return false; 100 } 101 102 private: 103 104 using INHERITED = Sample; 105 }; 106 107 ////////////////////////////////////////////////////////////////////////////// 108 109 DEF_SAMPLE( return new SampleSG(); ) 110