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 
17 class GrContext;
18 class SkCanvas;
19 class SkSurface;
20 
21 namespace sk_app {
22 
23 class WindowContext;
24 
25 class Window {
26 public:
27     static Window* CreateNativeWindow(void* platformData);
28 
~Window()29     virtual ~Window() { this->detach(); }
30 
31     virtual void setTitle(const char*) = 0;
32     virtual void show() = 0;
setUIState(const Json::Value & state)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 
scaleContentToFit()40     virtual bool scaleContentToFit() const { return false; }
supportsContentRect()41     virtual bool supportsContentRect() const { return false; }
getContentRect()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 
registerBackendCreatedFunc(OnBackendCreatedFunc func,void * userData)142     void registerBackendCreatedFunc(OnBackendCreatedFunc func, void* userData) {
143         fBackendCreatedFunc = func;
144         fBackendCreatedUserData = userData;
145     }
146 
registerCharFunc(OnCharFunc func,void * userData)147     void registerCharFunc(OnCharFunc func, void* userData) {
148         fCharFunc = func;
149         fCharUserData = userData;
150     }
151 
registerKeyFunc(OnKeyFunc func,void * userData)152     void registerKeyFunc(OnKeyFunc func, void* userData) {
153         fKeyFunc = func;
154         fKeyUserData = userData;
155     }
156 
registerMouseFunc(OnMouseFunc func,void * userData)157     void registerMouseFunc(OnMouseFunc func, void* userData) {
158         fMouseFunc = func;
159         fMouseUserData = userData;
160     }
161 
registerMouseWheelFunc(OnMouseWheelFunc func,void * userData)162     void registerMouseWheelFunc(OnMouseWheelFunc func, void* userData) {
163         fMouseWheelFunc = func;
164         fMouseWheelUserData = userData;
165     }
166 
registerPaintFunc(OnPaintFunc func,void * userData)167     void registerPaintFunc(OnPaintFunc func, void* userData) {
168         fPaintFunc = func;
169         fPaintUserData = userData;
170     }
171 
registerTouchFunc(OnTouchFunc func,void * userData)172     void registerTouchFunc(OnTouchFunc func, void* userData) {
173         fTouchFunc = func;
174         fTouchUserData = userData;
175     }
176 
registerUIStateChangedFunc(OnUIStateChangedFunc func,void * userData)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 
getRequestedDisplayParams()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 
205 protected:
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