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