xref: /third_party/skia/tools/sk_app/Window.h (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#ifndef Window_DEFINED
9#define Window_DEFINED
10
11#include "include/core/SkRect.h"
12#include "include/core/SkTypes.h"
13#include "include/private/SkTDArray.h"
14#include "tools/sk_app/DisplayParams.h"
15#include "tools/skui/InputState.h"
16#include "tools/skui/Key.h"
17#include "tools/skui/ModifierKey.h"
18
19#include <functional>
20
21class GrDirectContext;
22class SkCanvas;
23class SkSurface;
24class SkSurfaceProps;
25class SkString;
26
27namespace skgpu {
28class Context;
29}
30
31namespace sk_app {
32
33class WindowContext;
34
35class Window {
36public:
37    static Window* CreateNativeWindow(void* platformData);
38
39    virtual ~Window();
40
41    virtual void setTitle(const char*) = 0;
42    virtual void show() = 0;
43
44    // JSON-formatted UI state for Android. Do nothing by default
45    virtual void setUIState(const char*) {}
46
47    // Interface to the system clipboard. Only implemented on UNIX.
48    virtual const char* getClipboardText() { return nullptr; }
49    virtual void        setClipboardText(const char*) {}
50
51    // Schedules an invalidation event for window if one is not currently pending.
52    // Make sure that either onPaint or markInvalReceived is called when the client window consumes
53    // the the inval event. They unset fIsContentInvalided which allow future onInval.
54    void inval();
55
56    virtual bool scaleContentToFit() const { return false; }
57
58    enum BackendType {
59#ifdef SK_GL
60        kNativeGL_BackendType,
61#endif
62#if SK_ANGLE && defined(SK_BUILD_FOR_WIN)
63        kANGLE_BackendType,
64#endif
65#ifdef SK_DAWN
66        kDawn_BackendType,
67#endif
68#ifdef SK_VULKAN
69        kVulkan_BackendType,
70#endif
71#ifdef SK_METAL
72        kMetal_BackendType,
73#ifdef SK_GRAPHITE_ENABLED
74        kGraphiteMetal_BackendType,
75#endif
76#endif
77#ifdef SK_DIRECT3D
78        kDirect3D_BackendType,
79#endif
80        kRaster_BackendType,
81
82        kLast_BackendType = kRaster_BackendType
83    };
84    enum {
85        kBackendTypeCount = kLast_BackendType + 1
86    };
87
88    virtual bool attach(BackendType) = 0;
89    void detach();
90
91    // input handling
92
93    class Layer {
94    public:
95        Layer() : fActive(true) {}
96        virtual ~Layer() = default;
97
98        bool getActive() { return fActive; }
99        void setActive(bool active) { fActive = active; }
100
101        // return value of 'true' means 'I have handled this event'
102        virtual void onBackendCreated() {}
103        virtual void onAttach(Window* window) {}
104        virtual bool onChar(SkUnichar c, skui::ModifierKey) { return false; }
105        virtual bool onKey(skui::Key, skui::InputState, skui::ModifierKey) { return false; }
106        virtual bool onMouse(int x, int y, skui::InputState, skui::ModifierKey) { return false; }
107        virtual bool onMouseWheel(float delta, skui::ModifierKey) { return false; }
108        virtual bool onTouch(intptr_t owner, skui::InputState, float x, float y) { return false; }
109        // Platform-detected gesture events
110        virtual bool onFling(skui::InputState state) { return false; }
111        virtual bool onPinch(skui::InputState state, float scale, float x, float y) { return false; }
112        virtual void onUIStateChanged(const SkString& stateName, const SkString& stateValue) {}
113        virtual void onPrePaint() {}
114        virtual void onPaint(SkSurface*) {}
115        virtual void onResize(int width, int height) {}
116
117    private:
118        friend class Window;
119        bool fActive;
120    };
121
122    void pushLayer(Layer* layer) {
123        layer->onAttach(this);
124        fLayers.push_back(layer);
125    }
126
127    void onBackendCreated();
128    bool onChar(SkUnichar c, skui::ModifierKey modifiers);
129    bool onKey(skui::Key key, skui::InputState state, skui::ModifierKey modifiers);
130    bool onMouse(int x, int y, skui::InputState state, skui::ModifierKey modifiers);
131    bool onMouseWheel(float delta, skui::ModifierKey modifiers);
132    bool onTouch(intptr_t owner, skui::InputState state, float x, float y);  // multi-owner = multi-touch
133    // Platform-detected gesture events
134    bool onFling(skui::InputState state);
135    bool onPinch(skui::InputState state, float scale, float x, float y);
136    void onUIStateChanged(const SkString& stateName, const SkString& stateValue);
137    void onPaint();
138    void onResize(int width, int height);
139    void onActivate(bool isActive);
140
141    int width() const;
142    int height() const;
143    virtual float scaleFactor() const { return 1.0f; }
144
145    virtual const DisplayParams& getRequestedDisplayParams() { return fRequestedDisplayParams; }
146    virtual void setRequestedDisplayParams(const DisplayParams&, bool allowReattach = true);
147
148    // Actual parameters in effect, obtained from the native window.
149    int sampleCount() const;
150    int stencilBits() const;
151
152    // Returns null if there is not a GPU backend or if the backend is not yet created.
153    GrDirectContext* directContext() const;
154    skgpu::Context* graphiteContext() const;
155
156protected:
157    Window();
158
159    SkTDArray<Layer*>      fLayers;
160    DisplayParams          fRequestedDisplayParams;
161    bool                   fIsActive = true;
162
163    std::unique_ptr<WindowContext> fWindowContext;
164
165    virtual void onInval() = 0;
166
167    // Uncheck fIsContentInvalided to allow future inval/onInval.
168    void markInvalProcessed();
169
170    bool fIsContentInvalidated = false;  // use this to avoid duplicate invalidate events
171
172    void visitLayers(std::function<void(Layer*)> visitor);
173    bool signalLayers(std::function<bool(Layer*)> visitor);
174};
175
176}   // namespace sk_app
177#endif
178