xref: /aosp_15_r20/external/skia/tools/viewer/SGSlide.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 "include/private/base/SkTDArray.h"
13 #include "modules/sksg/include/SkSGDraw.h"
14 #include "modules/sksg/include/SkSGGroup.h"
15 #include "modules/sksg/include/SkSGPaint.h"
16 #include "modules/sksg/include/SkSGRect.h"
17 #include "modules/sksg/include/SkSGScene.h"
18 #include "tools/viewer/ClickHandlerSlide.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 SGSlide : public ClickHandlerSlide {
30     // TODO(kjlubick) use a vector instead of our private SkTDArray
31     SkTDArray<PerNodeInfo> fSideCar;
32     sk_sp<sksg::Group> fGroup;
33     std::unique_ptr<sksg::Scene> fScene;
34 
findInfo(sksg::Draw * key)35     PerNodeInfo* findInfo(sksg::Draw* key) {
36         for (int i = 0; i < fSideCar.size(); ++i) {
37             if (fSideCar[i].fDraw == key) {
38                 return &fSideCar[i];
39             }
40         }
41         return nullptr;
42     }
43 
appendNode(sk_sp<sksg::Draw> d,sk_sp<sksg::GeometryNode> g,sk_sp<sksg::PaintNode> p)44     void appendNode(sk_sp<sksg::Draw> d, sk_sp<sksg::GeometryNode> g, sk_sp<sksg::PaintNode> p) {
45         fGroup->addChild(d);
46         auto sc = fSideCar.append();
47         sc->fDraw  = d.get();
48         sc->fGeo   = g.get();
49         sc->fPaint = p.get();
50     }
51 
52 public:
SGSlide()53     SGSlide() {
54         fGroup = sksg::Group::Make();
55 
56         fScene = sksg::Scene::Make(fGroup);
57 
58         auto r = sksg::Rect::Make({20, 20, 400, 300});
59         auto p = sksg::Color::Make(SK_ColorRED);
60         auto d = sksg::Draw::Make(r, p);
61         this->appendNode(d, r, p);
62 
63         r = sksg::Rect::Make({60, 70, 300, 400});
64         p = sksg::Color::Make(SK_ColorBLUE);
65         d = sksg::Draw::Make(r, p);
66         this->appendNode(d, r, p);
67         fName = "SceneGraph";
68     }
69 
draw(SkCanvas * canvas)70     void draw(SkCanvas* canvas) override {
71         fScene->render(canvas);
72     }
73 
74 protected:
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 
103 //////////////////////////////////////////////////////////////////////////////
104 
105 DEF_SLIDE( return new SGSlide(); )
106