xref: /third_party/skia/samplecode/SampleSG.cpp (revision cb93a386)
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
20struct PerNodeInfo {
21    // key
22    sksg::Draw* fDraw;
23
24    // value(s)
25    sksg::GeometryNode* fGeo;
26    sksg::PaintNode*    fPaint;
27};
28
29class SampleSG : public Sample {
30    SkTDArray<PerNodeInfo> fSideCar;
31    sk_sp<sksg::Group> fGroup;
32    std::unique_ptr<sksg::Scene> fScene;
33
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
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
51public:
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
68protected:
69    SkString name() override { return SkString("SceneGraph"); }
70
71    void onDrawContent(SkCanvas* canvas) override {
72        fScene->render(canvas);
73    }
74
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
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
102private:
103
104    using INHERITED = Sample;
105};
106
107//////////////////////////////////////////////////////////////////////////////
108
109DEF_SAMPLE( return new SampleSG(); )
110