1/*
2 * Copyright 2011 Skia
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 SampleApp_DEFINED
9#define SampleApp_DEFINED
10
11#include "SkOSMenu.h"
12#include "SkPath.h"
13#include "SkPicture.h"
14#include "SkPictureRecorder.h"
15#include "SkScalar.h"
16#include "SkTDArray.h"
17#include "SkTouchGesture.h"
18#include "SkWindow.h"
19
20class GrContext;
21class GrRenderTarget;
22
23class SkCanvas;
24class SkData;
25class SkEvent;
26class SkTypeface;
27class SkViewFactory;
28
29class SampleWindow : public SkOSWindow {
30    SkTDArray<const SkViewFactory*> fSamples;
31public:
32    enum DeviceType {
33        kRaster_DeviceType,
34        kPicture_DeviceType,
35#if SK_SUPPORT_GPU
36        kGPU_DeviceType,
37#if SK_ANGLE
38        kANGLE_DeviceType,
39#endif // SK_ANGLE
40        kNullGPU_DeviceType,
41#endif // SK_SUPPORT_GPU
42
43        kDeviceTypeCnt
44    };
45
46    static bool IsGpuDeviceType(DeviceType devType) {
47    #if SK_SUPPORT_GPU
48        switch (devType) {
49            case kGPU_DeviceType:
50    #if SK_ANGLE
51            case kANGLE_DeviceType:
52    #endif // SK_ANGLE
53            case kNullGPU_DeviceType:
54                return true;
55            default:
56                return false;
57        }
58    #endif // SK_SUPPORT_GPU
59        return false;
60    }
61
62    /**
63     * SampleApp ports can subclass this manager class if they want to:
64     *      * filter the types of devices supported
65     *      * customize plugging of SkBaseDevice objects into an SkCanvas
66     *      * customize publishing the results of draw to the OS window
67     *      * manage GrContext / GrRenderTarget lifetimes
68     */
69    class DeviceManager : public SkRefCnt {
70    public:
71        SK_DECLARE_INST_COUNT(DeviceManager)
72
73        virtual void setUpBackend(SampleWindow* win, int msaaSampleCount) = 0;
74
75        virtual void tearDownBackend(SampleWindow* win) = 0;
76
77        // called before drawing. should install correct device
78        // type on the canvas. Will skip drawing if returns false.
79        virtual SkCanvas* createCanvas(DeviceType dType, SampleWindow* win) = 0;
80
81        // called after drawing, should get the results onto the
82        // screen.
83        virtual void publishCanvas(DeviceType dType,
84                                   SkCanvas* canvas,
85                                   SampleWindow* win) = 0;
86
87        // called when window changes size, guaranteed to be called
88        // at least once before first draw (after init)
89        virtual void windowSizeChanged(SampleWindow* win) = 0;
90
91        // return the GrContext backing gpu devices (NULL if not built with GPU support)
92        virtual GrContext* getGrContext() = 0;
93
94        // return the GrRenderTarget backing gpu devices (NULL if not built with GPU support)
95        virtual GrRenderTarget* getGrRenderTarget() = 0;
96    private:
97        typedef SkRefCnt INHERITED;
98    };
99
100    SampleWindow(void* hwnd, int argc, char** argv, DeviceManager*);
101    virtual ~SampleWindow();
102
103    virtual SkCanvas* createCanvas() SK_OVERRIDE {
104        SkCanvas* canvas = NULL;
105        if (fDevManager) {
106            canvas = fDevManager->createCanvas(fDeviceType, this);
107        }
108        if (NULL == canvas) {
109            canvas = this->INHERITED::createCanvas();
110        }
111        return canvas;
112    }
113
114    virtual void draw(SkCanvas* canvas);
115
116    void setDeviceType(DeviceType type);
117    void toggleRendering();
118    void toggleSlideshow();
119    void toggleFPS();
120    void showOverview();
121
122    GrContext* getGrContext() const { return fDevManager->getGrContext(); }
123
124    void setZoomCenter(float x, float y);
125    void changeZoomLevel(float delta);
126    bool nextSample();
127    bool previousSample();
128    bool goToSample(int i);
129    SkString getSampleTitle(int i);
130    int  sampleCount();
131    bool handleTouch(int ownerId, float x, float y,
132            SkView::Click::State state);
133    void saveToPdf();
134    SkData* getPDFData() { return fPDFData; }
135    void postInvalDelay();
136
137    DeviceType getDeviceType() const { return fDeviceType; }
138
139protected:
140    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE;
141    virtual bool onHandleKey(SkKey key) SK_OVERRIDE;
142    virtual bool onHandleChar(SkUnichar) SK_OVERRIDE;
143    virtual void onSizeChange() SK_OVERRIDE;
144
145    virtual SkCanvas* beforeChildren(SkCanvas*) SK_OVERRIDE;
146    virtual void afterChildren(SkCanvas*) SK_OVERRIDE;
147    virtual void beforeChild(SkView* child, SkCanvas* canvas) SK_OVERRIDE;
148    virtual void afterChild(SkView* child, SkCanvas* canvas) SK_OVERRIDE;
149
150    virtual bool onEvent(const SkEvent& evt) SK_OVERRIDE;
151    virtual bool onQuery(SkEvent* evt) SK_OVERRIDE;
152
153    virtual bool onDispatchClick(int x, int y, Click::State, void* owner,
154                                 unsigned modi) SK_OVERRIDE;
155    virtual bool onClick(Click* click) SK_OVERRIDE;
156    virtual Click* onFindClickHandler(SkScalar x, SkScalar y,
157                                      unsigned modi) SK_OVERRIDE;
158
159private:
160    class DefaultDeviceManager;
161
162    int fCurrIndex;
163
164    SkPictureRecorder fRecorder;
165    SkPath fClipPath;
166
167    SkTouchGesture fGesture;
168    SkScalar fZoomLevel;
169    SkScalar fZoomScale;
170
171    DeviceType fDeviceType;
172    DeviceManager* fDevManager;
173
174    bool fSaveToPdf;
175    SkCanvas* fPdfCanvas;
176    SkData* fPDFData;
177
178    bool fUseClip;
179    bool fNClip;
180    bool fAnimating;
181    bool fRotate;
182    SkScalar fRotateAnimTime;
183    bool fPerspAnim;
184    SkScalar fPerspAnimTime;
185    bool fRequestGrabImage;
186    bool fMeasureFPS;
187    SkMSec fMeasureFPS_Time;
188    SkMSec fMeasureFPS_StartTime;
189    bool fMagnify;
190    int fTilingMode;
191
192
193    SkOSMenu::TriState fPipeState;  // Mixed uses a tiled pipe
194                                    // On uses a normal pipe
195                                    // Off uses no pipe
196    int  fUsePipeMenuItemID;
197
198    // The following are for the 'fatbits' drawing
199    // Latest position of the mouse.
200    int fMouseX, fMouseY;
201    int fFatBitsScale;
202    // Used by the text showing position and color values.
203    SkTypeface* fTypeface;
204    bool fShowZoomer;
205
206    SkOSMenu::TriState fLCDState;
207    SkOSMenu::TriState fAAState;
208    SkOSMenu::TriState fSubpixelState;
209    int fHintingState;
210    int fFilterLevelIndex;
211    unsigned   fFlipAxis;
212
213    int fMSAASampleCount;
214
215    int fScrollTestX, fScrollTestY;
216    SkScalar fZoomCenterX, fZoomCenterY;
217
218    //Stores global settings
219    SkOSMenu* fAppMenu; // We pass ownership to SkWindow, when we call addMenu
220    //Stores slide specific settings
221    SkOSMenu* fSlideMenu; // We pass ownership to SkWindow, when we call addMenu
222
223    int fTransitionNext;
224    int fTransitionPrev;
225
226    void loadView(SkView*);
227    void updateTitle();
228
229    bool zoomIn();
230    bool zoomOut();
231    void updatePointer(int x, int y);
232    void magnify(SkCanvas* canvas);
233    void showZoomer(SkCanvas* canvas);
234    void updateMatrix();
235    void postAnimatingEvent();
236    void installDrawFilter(SkCanvas*);
237    int findByTitle(const char*);
238    void listTitles();
239    SkSize tileSize() const;
240
241    typedef SkOSWindow INHERITED;
242};
243
244#endif
245