xref: /third_party/skia/samplecode/Sample.cpp (revision cb93a386)
1/*
2 * Copyright 2016 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/SkString.h"
10#include "samplecode/Sample.h"
11
12#if SK_SUPPORT_GPU
13#   include "include/gpu/GrDirectContext.h"
14#else
15class GrDirectContext;
16#endif
17
18//////////////////////////////////////////////////////////////////////////////
19
20void Sample::setSize(SkScalar width, SkScalar height) {
21    width = std::max(0.0f, width);
22    height = std::max(0.0f, height);
23
24    if (fWidth != width || fHeight != height)
25    {
26        fWidth = width;
27        fHeight = height;
28        this->onSizeChange();
29    }
30}
31
32void Sample::draw(SkCanvas* canvas) {
33    if (fWidth && fHeight) {
34        SkRect    r;
35        r.setLTRB(0, 0, fWidth, fHeight);
36        if (canvas->quickReject(r)) {
37            return;
38        }
39
40        SkAutoCanvasRestore    as(canvas, true);
41        int sc = canvas->save();
42
43        if (!fHaveCalledOnceBeforeDraw) {
44            fHaveCalledOnceBeforeDraw = true;
45            this->onOnceBeforeDraw();
46        }
47        this->onDrawBackground(canvas);
48
49        SkAutoCanvasRestore acr(canvas, true);
50        this->onDrawContent(canvas);
51#if SK_SUPPORT_GPU
52        // Ensure the context doesn't combine GrDrawOps across draw loops.
53        if (auto direct = GrAsDirectContext(canvas->recordingContext())) {
54            direct->flushAndSubmit();
55        }
56#endif
57
58        canvas->restoreToCount(sc);
59    }
60}
61
62////////////////////////////////////////////////////////////////////////////
63
64bool Sample::mouse(SkPoint point, skui::InputState clickState, skui::ModifierKey modifierKeys) {
65    auto dispatch = [this](Click* c) {
66        return c->fHasFunc ? c->fFunc(c) : this->onClick(c);
67    };
68
69    switch (clickState) {
70        case skui::InputState::kDown:
71            fClick = nullptr;
72            fClick.reset(this->onFindClickHandler(point.x(), point.y(), modifierKeys));
73            if (!fClick) {
74                return false;
75            }
76            fClick->fPrev = fClick->fCurr = fClick->fOrig = point;
77            fClick->fState = skui::InputState::kDown;
78            fClick->fModifierKeys = modifierKeys;
79            dispatch(fClick.get());
80            return true;
81        case skui::InputState::kMove:
82            if (fClick) {
83                fClick->fPrev = fClick->fCurr;
84                fClick->fCurr = point;
85                fClick->fState = skui::InputState::kMove;
86                fClick->fModifierKeys = modifierKeys;
87                return dispatch(fClick.get());
88            }
89            return false;
90        case skui::InputState::kUp:
91            if (fClick) {
92                fClick->fPrev = fClick->fCurr;
93                fClick->fCurr = point;
94                fClick->fState = skui::InputState::kUp;
95                fClick->fModifierKeys = modifierKeys;
96                bool result = dispatch(fClick.get());
97                fClick = nullptr;
98                return result;
99            }
100            return false;
101        default:
102            // Ignore other cases
103            SkASSERT(false);
104            break;
105    }
106    SkASSERT(false);
107    return false;
108}
109
110//////////////////////////////////////////////////////////////////////
111
112void Sample::onSizeChange() {}
113
114Sample::Click* Sample::onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) {
115    return nullptr;
116}
117
118bool Sample::onClick(Click*) {
119    return false;
120}
121
122void Sample::onDrawBackground(SkCanvas* canvas) {
123    canvas->drawColor(fBGColor);
124}
125
126// need to explicitly declare this, or we get some weird infinite loop llist
127template SampleRegistry* SampleRegistry::gHead;
128