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 "SkTDArray.h"
14 #include "SkTypes.h"
15 
16 class GrContext;
17 class SkCanvas;
18 class SkSurface;
19 class SkSurfaceProps;
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;
33 
34     // JSON-formatted UI state for Android. Do nothing by default
setUIState(const char *)35     virtual void setUIState(const char*) {}
36 
37     // Shedules an invalidation event for window if one is not currently pending.
38     // Make sure that either onPaint or markInvalReceived is called when the client window consumes
39     // the the inval event. They unset fIsContentInvalided which allow future onInval.
40     void inval();
41 
scaleContentToFit()42     virtual bool scaleContentToFit() const { return false; }
43 
44     enum BackendType {
45         kNativeGL_BackendType,
46 #if SK_ANGLE && defined(SK_BUILD_FOR_WIN)
47         kANGLE_BackendType,
48 #endif
49 #ifdef SK_VULKAN
50         kVulkan_BackendType,
51 #endif
52         kRaster_BackendType,
53 
54         kLast_BackendType = kRaster_BackendType
55     };
56     enum {
57         kBackendTypeCount = kLast_BackendType + 1
58     };
59 
60     virtual bool attach(BackendType) = 0;
61     void detach();
62 
63     // input handling
64     enum class Key {
65         kNONE,    //corresponds to android's UNKNOWN
66 
67         kLeftSoftKey,
68         kRightSoftKey,
69 
70         kHome,    //!< the home key - added to match android
71         kBack,    //!< (CLR)
72         kSend,    //!< the green (talk) key
73         kEnd,     //!< the red key
74 
75         k0,
76         k1,
77         k2,
78         k3,
79         k4,
80         k5,
81         k6,
82         k7,
83         k8,
84         k9,
85         kStar,    //!< the * key
86         kHash,    //!< the # key
87 
88         kUp,
89         kDown,
90         kLeft,
91         kRight,
92 
93         // Keys needed by ImGui
94         kTab,
95         kPageUp,
96         kPageDown,
97         kDelete,
98         kEscape,
99         kShift,
100         kCtrl,
101         kOption, // AKA Alt
102         kA,
103         kC,
104         kV,
105         kX,
106         kY,
107         kZ,
108 
109         kOK,      //!< the center key
110 
111         kVolUp,   //!< volume up    - match android
112         kVolDown, //!< volume down  - same
113         kPower,   //!< power button - same
114         kCamera,  //!< camera       - same
115 
116         kLast = kCamera
117     };
118     static const int kKeyCount = static_cast<int>(Key::kLast) + 1;
119 
120     enum ModifierKeys {
121         kShift_ModifierKey = 1 << 0,
122         kControl_ModifierKey = 1 << 1,
123         kOption_ModifierKey = 1 << 2,   // same as ALT
124         kCommand_ModifierKey = 1 << 3,
125         kFirstPress_ModifierKey = 1 << 4,
126     };
127 
128     enum InputState {
129         kDown_InputState,
130         kUp_InputState,
131         kMove_InputState   // only valid for mouse
132     };
133 
134     class Layer {
135     public:
Layer()136         Layer() : fActive(true) {}
137         virtual ~Layer() = default;
138 
getActive()139         bool getActive() { return fActive; }
setActive(bool active)140         void setActive(bool active) { fActive = active; }
141 
142         // return value of 'true' means 'I have handled this event'
onBackendCreated()143         virtual void onBackendCreated() {}
onAttach(Window * window)144         virtual void onAttach(Window* window) {}
onChar(SkUnichar c,uint32_t modifiers)145         virtual bool onChar(SkUnichar c, uint32_t modifiers) { return false; }
onKey(Key key,InputState state,uint32_t modifiers)146         virtual bool onKey(Key key, InputState state, uint32_t modifiers) { return false; }
onMouse(int x,int y,InputState state,uint32_t modifiers)147         virtual bool onMouse(int x, int y, InputState state, uint32_t modifiers) { return false; }
onMouseWheel(float delta,uint32_t modifiers)148         virtual bool onMouseWheel(float delta, uint32_t modifiers) { return false; }
onTouch(intptr_t owner,InputState state,float x,float y)149         virtual bool onTouch(intptr_t owner, InputState state, float x, float y) { return false; }
onUIStateChanged(const SkString & stateName,const SkString & stateValue)150         virtual void onUIStateChanged(const SkString& stateName, const SkString& stateValue) {}
onPrePaint()151         virtual void onPrePaint() {}
onPaint(SkCanvas *)152         virtual void onPaint(SkCanvas*) {}
onResize(int width,int height)153         virtual void onResize(int width, int height) {}
154 
155     private:
156         friend class Window;
157         bool fActive;
158     };
159 
pushLayer(Layer * layer)160     void pushLayer(Layer* layer) {
161         layer->onAttach(this);
162         fLayers.push_back(layer);
163     }
164 
165     void onBackendCreated();
166     bool onChar(SkUnichar c, uint32_t modifiers);
167     bool onKey(Key key, InputState state, uint32_t modifiers);
168     bool onMouse(int x, int y, InputState state, uint32_t modifiers);
169     bool onMouseWheel(float delta, uint32_t modifiers);
170     bool onTouch(intptr_t owner, InputState state, float x, float y);  // multi-owner = multi-touch
171     void onUIStateChanged(const SkString& stateName, const SkString& stateValue);
172     void onPaint();
173     void onResize(int width, int height);
174 
175     int width();
176     int height();
177 
getRequestedDisplayParams()178     virtual const DisplayParams& getRequestedDisplayParams() { return fRequestedDisplayParams; }
179     virtual void setRequestedDisplayParams(const DisplayParams&, bool allowReattach = true);
180 
181     // Actual parameters in effect, obtained from the native window.
182     int sampleCount() const;
183     int stencilBits() const;
184 
185     // Returns null if there is not a GPU backend or if the backend is not yet created.
186     GrContext* getGrContext() const;
187 
188 protected:
189     Window();
190 
191     SkTDArray<Layer*>      fLayers;
192     DisplayParams          fRequestedDisplayParams;
193 
194     WindowContext* fWindowContext = nullptr;
195 
196     virtual void onInval() = 0;
197 
198     // Uncheck fIsContentInvalided to allow future inval/onInval.
199     void markInvalProcessed();
200 
201     bool fIsContentInvalidated = false;  // use this to avoid duplicate invalidate events
202 
203     void visitLayers(std::function<void(Layer*)> visitor);
204     bool signalLayers(std::function<bool(Layer*)> visitor);
205 };
206 
207 }   // namespace sk_app
208 #endif
209