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 "DisplayParams.h"
12#include "SkRect.h"
13#include "SkTouchGesture.h"
14#include "SkTypes.h"
15#include "SkJSONCPP.h"
16
17class GrContext;
18class SkCanvas;
19class SkSurface;
20
21namespace sk_app {
22
23class WindowContext;
24
25class Window {
26public:
27    static Window* CreateNativeWindow(void* platformData);
28
29    virtual ~Window() { this->detach(); }
30
31    virtual void setTitle(const char*) = 0;
32    virtual void show() = 0;
33    virtual void setUIState(const Json::Value& state) {}  // do nothing in default
34
35    // Shedules an invalidation event for window if one is not currently pending.
36    // Make sure that either onPaint or markInvalReceived is called when the client window consumes
37    // the the inval event. They unset fIsContentInvalided which allow future onInval.
38    void inval();
39
40    virtual bool scaleContentToFit() const { return false; }
41    virtual bool supportsContentRect() const { return false; }
42    virtual SkRect getContentRect() { return SkRect::MakeEmpty(); }
43
44    enum BackendType {
45        kNativeGL_BackendType,
46#ifdef SK_VULKAN
47        kVulkan_BackendType,
48#endif
49        kRaster_BackendType,
50
51        kLast_BackendType = kRaster_BackendType
52    };
53    enum {
54        kBackendTypeCount = kLast_BackendType + 1
55    };
56
57    virtual bool attach(BackendType) = 0;
58    void detach();
59
60    // input handling
61    enum class Key {
62        kNONE,    //corresponds to android's UNKNOWN
63
64        kLeftSoftKey,
65        kRightSoftKey,
66
67        kHome,    //!< the home key - added to match android
68        kBack,    //!< (CLR)
69        kSend,    //!< the green (talk) key
70        kEnd,     //!< the red key
71
72        k0,
73        k1,
74        k2,
75        k3,
76        k4,
77        k5,
78        k6,
79        k7,
80        k8,
81        k9,
82        kStar,    //!< the * key
83        kHash,    //!< the # key
84
85        kUp,
86        kDown,
87        kLeft,
88        kRight,
89
90        // Keys needed by ImGui
91        kTab,
92        kPageUp,
93        kPageDown,
94        kDelete,
95        kEscape,
96        kShift,
97        kCtrl,
98        kOption, // AKA Alt
99        kA,
100        kC,
101        kV,
102        kX,
103        kY,
104        kZ,
105
106        kOK,      //!< the center key
107
108        kVolUp,   //!< volume up    - match android
109        kVolDown, //!< volume down  - same
110        kPower,   //!< power button - same
111        kCamera,  //!< camera       - same
112
113        kLast = kCamera
114    };
115    static const int kKeyCount = static_cast<int>(Key::kLast) + 1;
116
117    enum ModifierKeys {
118        kShift_ModifierKey = 1 << 0,
119        kControl_ModifierKey = 1 << 1,
120        kOption_ModifierKey = 1 << 2,   // same as ALT
121        kCommand_ModifierKey = 1 << 3,
122        kFirstPress_ModifierKey = 1 << 4,
123    };
124
125    enum InputState {
126        kDown_InputState,
127        kUp_InputState,
128        kMove_InputState   // only valid for mouse
129    };
130
131    // return value of 'true' means 'I have handled this event'
132    typedef void(*OnBackendCreatedFunc)(void* userData);
133    typedef bool(*OnCharFunc)(SkUnichar c, uint32_t modifiers, void* userData);
134    typedef bool(*OnKeyFunc)(Key key, InputState state, uint32_t modifiers, void* userData);
135    typedef bool(*OnMouseFunc)(int x, int y, InputState state, uint32_t modifiers, void* userData);
136    typedef bool(*OnMouseWheelFunc)(float delta, uint32_t modifiers, void* userData);
137    typedef bool(*OnTouchFunc)(intptr_t owner, InputState state, float x, float y, void* userData);
138    typedef void(*OnUIStateChangedFunc)(
139            const SkString& stateName, const SkString& stateValue, void* userData);
140    typedef void(*OnPaintFunc)(SkCanvas*, void* userData);
141
142    void registerBackendCreatedFunc(OnBackendCreatedFunc func, void* userData) {
143        fBackendCreatedFunc = func;
144        fBackendCreatedUserData = userData;
145    }
146
147    void registerCharFunc(OnCharFunc func, void* userData) {
148        fCharFunc = func;
149        fCharUserData = userData;
150    }
151
152    void registerKeyFunc(OnKeyFunc func, void* userData) {
153        fKeyFunc = func;
154        fKeyUserData = userData;
155    }
156
157    void registerMouseFunc(OnMouseFunc func, void* userData) {
158        fMouseFunc = func;
159        fMouseUserData = userData;
160    }
161
162    void registerMouseWheelFunc(OnMouseWheelFunc func, void* userData) {
163        fMouseWheelFunc = func;
164        fMouseWheelUserData = userData;
165    }
166
167    void registerPaintFunc(OnPaintFunc func, void* userData) {
168        fPaintFunc = func;
169        fPaintUserData = userData;
170    }
171
172    void registerTouchFunc(OnTouchFunc func, void* userData) {
173        fTouchFunc = func;
174        fTouchUserData = userData;
175    }
176
177    void registerUIStateChangedFunc(OnUIStateChangedFunc func, void* userData) {
178        fUIStateChangedFunc = func;
179        fUIStateChangedUserData = userData;
180    }
181
182    void onBackendCreated();
183    bool onChar(SkUnichar c, uint32_t modifiers);
184    bool onKey(Key key, InputState state, uint32_t modifiers);
185    bool onMouse(int x, int y, InputState state, uint32_t modifiers);
186    bool onMouseWheel(float delta, uint32_t modifiers);
187    bool onTouch(intptr_t owner, InputState state, float x, float y);  // multi-owner = multi-touch
188    void onUIStateChanged(const SkString& stateName, const SkString& stateValue);
189    void onPaint();
190    void onResize(int width, int height);
191
192    int width();
193    int height();
194
195    virtual const DisplayParams& getRequestedDisplayParams() { return fRequestedDisplayParams; }
196    virtual void setRequestedDisplayParams(const DisplayParams&);
197
198    // Actual parameters in effect, obtained from the native window.
199    int sampleCount() const;
200    int stencilBits() const;
201
202    // Returns null if there is not a GPU backend or if the backend is not yet created.
203    const GrContext* getGrContext() const;
204
205protected:
206    Window();
207
208    OnBackendCreatedFunc   fBackendCreatedFunc;
209    void*                  fBackendCreatedUserData;
210    OnCharFunc             fCharFunc;
211    void*                  fCharUserData;
212    OnKeyFunc              fKeyFunc;
213    void*                  fKeyUserData;
214    OnMouseFunc            fMouseFunc;
215    void*                  fMouseUserData;
216    OnMouseWheelFunc       fMouseWheelFunc;
217    void*                  fMouseWheelUserData;
218    OnTouchFunc            fTouchFunc;
219    void*                  fTouchUserData;
220    OnUIStateChangedFunc   fUIStateChangedFunc;
221    void*                  fUIStateChangedUserData;
222    OnPaintFunc            fPaintFunc;
223    void*                  fPaintUserData;
224    DisplayParams          fRequestedDisplayParams;
225
226    WindowContext* fWindowContext = nullptr;
227
228    virtual void onInval() = 0;
229
230    // Uncheck fIsContentInvalided to allow future inval/onInval.
231    void markInvalProcessed();
232
233    bool fIsContentInvalidated = false;  // use this to avoid duplicate invalidate events
234};
235
236}   // namespace sk_app
237#endif
238