blob: 1f1bb4bdc5ece5f356e16a4c1a7715d8b01e4ad8 [file] [log] [blame]
Ben Wagnerb2c4ea62018-08-08 11:36:17 -04001/*
2 * Copyright 2011 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 SampleCode_DEFINED
9#define SampleCode_DEFINED
10
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkColor.h"
12#include "include/core/SkPoint.h"
13#include "include/core/SkRefCnt.h"
14#include "include/core/SkString.h"
15#include "include/private/SkMacros.h"
16#include "src/utils/SkMetaData.h"
17#include "tools/Registry.h"
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040018
Mike Kleincd5104e2019-03-20 11:55:08 -050019class AnimTimer;
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040020class SkCanvas;
21class Sample;
22
23using SampleFactory = Sample* (*)();
24using SampleRegistry = sk_tools::Registry<SampleFactory>;
25
26#define DEF_SAMPLE(code) \
27 static Sample* SK_MACRO_APPEND_LINE(F_)() { code } \
28 static SampleRegistry SK_MACRO_APPEND_LINE(R_)(SK_MACRO_APPEND_LINE(F_));
29
30///////////////////////////////////////////////////////////////////////////////
31
32class Sample : public SkRefCnt {
33public:
34 Sample()
35 : fBGColor(SK_ColorWHITE)
36 , fWidth(0), fHeight(0)
37 , fHaveCalledOnceBeforeDraw(false)
38 {}
39
40 SkScalar width() const { return fWidth; }
41 SkScalar height() const { return fHeight; }
42 void setSize(SkScalar width, SkScalar height);
43 void setSize(const SkPoint& size) { this->setSize(size.fX, size.fY); }
44 void setWidth(SkScalar width) { this->setSize(width, fHeight); }
45 void setHeight(SkScalar height) { this->setSize(fWidth, height); }
46
47 /** Call this to have the view draw into the specified canvas. */
48 virtual void draw(SkCanvas* canvas);
49
50 // Click handling
51 class Click {
52 public:
53 Click(Sample* target);
54 virtual ~Click();
55
56 enum State {
57 kDown_State,
58 kMoved_State,
59 kUp_State
60 };
61 enum ModifierKeys {
62 kShift_ModifierKey = 1 << 0,
63 kControl_ModifierKey = 1 << 1,
64 kOption_ModifierKey = 1 << 2, // same as ALT
65 kCommand_ModifierKey = 1 << 3,
66 };
67 SkPoint fOrig, fPrev, fCurr;
68 SkIPoint fIOrig, fIPrev, fICurr;
69 State fState;
70 unsigned fModifierKeys;
71
72 SkMetaData fMeta;
73 private:
74 sk_sp<Sample> fTarget;
75
76 friend class Sample;
77 };
78 Click* findClickHandler(SkScalar x, SkScalar y, unsigned modifierKeys);
79 static void DoClickDown(Click*, int x, int y, unsigned modi);
80 static void DoClickMoved(Click*, int x, int y, unsigned modi);
81 static void DoClickUp(Click*, int x, int y, unsigned modi);
82
83 void setBGColor(SkColor color) { fBGColor = color; }
Mike Kleincd5104e2019-03-20 11:55:08 -050084 bool animate(const AnimTimer& timer) { return this->onAnimate(timer); }
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040085
86 class Event {
87 public:
88 Event();
89 explicit Event(const char type[]);
90 Event(const Event& src);
91 ~Event();
92
93 /** Returns true if the event's type matches exactly the specified type (case sensitive) */
94 bool isType(const char type[]) const;
95
96 /** Return the event's unnamed 32bit field. Default value is 0 */
97 uint32_t getFast32() const { return f32; }
98
99 /** Set the event's unnamed 32bit field. */
100 void setFast32(uint32_t x) { f32 = x; }
101
102 /** Return true if the event contains the named 32bit field, and return the field
103 in value (if value is non-null). If there is no matching named field, return false
104 and ignore the value parameter.
105 */
106 bool findS32(const char name[], int32_t* value = nullptr) const {
107 return fMeta.findS32(name, value);
108 }
109 /** Return true if the event contains the named SkScalar field, and return the field
110 in value (if value is non-null). If there is no matching named field, return false
111 and ignore the value parameter.
112 */
113 bool findScalar(const char name[], SkScalar* value = nullptr) const {
114 return fMeta.findScalar(name, value);
115 }
116 /** Return true if the event contains the named SkScalar field, and return the fields
117 in value[] (if value is non-null), and return the number of SkScalars in count
118 (if count is non-null). If there is no matching named field, return false
119 and ignore the value and count parameters.
120 */
121 const SkScalar* findScalars(const char name[], int* count, SkScalar values[]=nullptr) const{
122 return fMeta.findScalars(name, count, values);
123 }
124 /** Return the value of the named string field, or nullptr. */
125 const char* findString(const char name[]) const { return fMeta.findString(name); }
126 /** Return true if the event contains the named pointer field, and return the field
127 in value (if value is non-null). If there is no matching named field, return false
128 and ignore the value parameter.
129 */
130 bool findPtr(const char name[], void** value) const { return fMeta.findPtr(name, value); }
131 bool findBool(const char name[], bool* value) const { return fMeta.findBool(name, value); }
132 const void* findData(const char name[], size_t* byteCount = nullptr) const {
133 return fMeta.findData(name, byteCount);
134 }
135
136 /** Returns true if ethe event contains the named 32bit field, and if it equals the specified value */
137 bool hasS32(const char name[], int32_t value) const { return fMeta.hasS32(name, value); }
138 /** Returns true if ethe event contains the named SkScalar field, and if it equals the specified value */
139 bool hasScalar(const char name[], SkScalar value) const { return fMeta.hasScalar(name, value); }
140 /** Returns true if ethe event contains the named string field, and if it equals (using strcmp) the specified value */
141 bool hasString(const char name[], const char value[]) const { return fMeta.hasString(name, value); }
142 /** Returns true if ethe event contains the named pointer field, and if it equals the specified value */
143 bool hasPtr(const char name[], void* value) const { return fMeta.hasPtr(name, value); }
144 bool hasBool(const char name[], bool value) const { return fMeta.hasBool(name, value); }
145 bool hasData(const char name[], const void* data, size_t byteCount) const {
146 return fMeta.hasData(name, data, byteCount);
147 }
148
149 /** Add/replace the named 32bit field to the event. */
150 void setS32(const char name[], int32_t value) { fMeta.setS32(name, value); }
151 /** Add/replace the named SkScalar field to the event. */
152 void setScalar(const char name[], SkScalar value) { fMeta.setScalar(name, value); }
153 /** Add/replace the named SkScalar[] field to the event. */
154 SkScalar* setScalars(const char name[], int count, const SkScalar values[] = nullptr) {
155 return fMeta.setScalars(name, count, values);
156 }
157 /** Add/replace the named string field to the event. */
158 void setString(const char name[], const char value[]) { fMeta.setString(name, value); }
159 /** Add/replace the named pointer field to the event. */
160 void setPtr(const char name[], void* value) { fMeta.setPtr(name, value); }
161 void setBool(const char name[], bool value) { fMeta.setBool(name, value); }
162 void setData(const char name[], const void* data, size_t byteCount) {
163 fMeta.setData(name, data, byteCount);
164 }
165
166 /** Return the underlying metadata object */
167 SkMetaData& getMetaData() { return fMeta; }
168 /** Return the underlying metadata object */
169 const SkMetaData& getMetaData() const { return fMeta; }
170
171 ///////////////////////////////////////////////////////////////////////////
172
173 private:
174 SkMetaData fMeta;
175 SkString fType;
176 uint32_t f32;
177 };
178
179 /** Pass an event to this object for processing. Returns true if the event was handled. */
180 bool doEvent(const Event&);
181
182 /** Returns true if the sink (or one of its subclasses) understands the event as a query.
183 If so, the sink may modify the event to communicate its "answer".
184 */
185 bool doQuery(Event* query);
186
187 static const char* kCharEvtName;
188 static const char* kTitleEvtName;
189 static bool CharQ(const Event&, SkUnichar* outUni);
190 static bool TitleQ(const Event&);
191 static void TitleR(Event*, const char title[]);
192 static bool RequestTitle(Sample* view, SkString* title);
193
194protected:
195 /** Override to handle events in your subclass.
196 * Overriders must call the super class for unhandled events.
197 */
198 virtual bool onEvent(const Event&);
199 virtual bool onQuery(Event*);
200
201 /** Override to be notified of size changes. Overriders must call the super class. */
202 virtual void onSizeChange();
203
204 /** Override this if you might handle the click */
205 virtual Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi);
206
207 /** Override to track clicks. Return true as long as you want to track the pen/mouse. */
208 virtual bool onClick(Click*);
209
210 virtual void onDrawBackground(SkCanvas*);
211 virtual void onDrawContent(SkCanvas*) = 0;
Mike Kleincd5104e2019-03-20 11:55:08 -0500212 virtual bool onAnimate(const AnimTimer&) { return false; }
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400213 virtual void onOnceBeforeDraw() {}
214
215private:
216 SkColor fBGColor;
217 SkScalar fWidth, fHeight;
218 bool fHaveCalledOnceBeforeDraw;
219};
220
221#endif