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