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