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 21 class GrDirectContext; 22 class SkCanvas; 23 class SkSurface; 24 class SkSurfaceProps; 25 class SkString; 26 27 namespace skgpu { 28 class Context; 29 } 30 31 namespace sk_app { 32 33 class WindowContext; 34 35 class Window { 36 public: 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 setUIState(const char *)45 virtual void setUIState(const char*) {} 46 47 // Interface to the system clipboard. Only implemented on UNIX. getClipboardText()48 virtual const char* getClipboardText() { return nullptr; } setClipboardText(const char *)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 scaleContentToFit()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: Layer()95 Layer() : fActive(true) {} 96 virtual ~Layer() = default; 97 getActive()98 bool getActive() { return fActive; } setActive(bool active)99 void setActive(bool active) { fActive = active; } 100 101 // return value of 'true' means 'I have handled this event' onBackendCreated()102 virtual void onBackendCreated() {} onAttach(Window * window)103 virtual void onAttach(Window* window) {} onChar(SkUnichar c,skui::ModifierKey)104 virtual bool onChar(SkUnichar c, skui::ModifierKey) { return false; } onKey(skui::Key,skui::InputState,skui::ModifierKey)105 virtual bool onKey(skui::Key, skui::InputState, skui::ModifierKey) { return false; } onMouse(int x,int y,skui::InputState,skui::ModifierKey)106 virtual bool onMouse(int x, int y, skui::InputState, skui::ModifierKey) { return false; } onMouseWheel(float delta,skui::ModifierKey)107 virtual bool onMouseWheel(float delta, skui::ModifierKey) { return false; } onTouch(intptr_t owner,skui::InputState,float x,float y)108 virtual bool onTouch(intptr_t owner, skui::InputState, float x, float y) { return false; } 109 // Platform-detected gesture events onFling(skui::InputState state)110 virtual bool onFling(skui::InputState state) { return false; } onPinch(skui::InputState state,float scale,float x,float y)111 virtual bool onPinch(skui::InputState state, float scale, float x, float y) { return false; } onUIStateChanged(const SkString & stateName,const SkString & stateValue)112 virtual void onUIStateChanged(const SkString& stateName, const SkString& stateValue) {} onPrePaint()113 virtual void onPrePaint() {} onPaint(SkSurface *)114 virtual void onPaint(SkSurface*) {} onResize(int width,int height)115 virtual void onResize(int width, int height) {} 116 117 private: 118 friend class Window; 119 bool fActive; 120 }; 121 pushLayer(Layer * layer)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; scaleFactor()143 virtual float scaleFactor() const { return 1.0f; } 144 getRequestedDisplayParams()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 156 protected: 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