1 /* 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 11 #include "Registry.h" 12 #include "SkColor.h" 13 #include "SkMacros.h" 14 #include "SkMetaData.h" 15 #include "SkPoint.h" 16 #include "SkRefCnt.h" 17 #include "SkString.h" 18 19 class SkAnimTimer; 20 class SkCanvas; 21 class Sample; 22 23 using SampleFactory = Sample* (*)(); 24 using 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 32 class Sample : public SkRefCnt { 33 public: Sample()34 Sample() 35 : fBGColor(SK_ColorWHITE) 36 , fWidth(0), fHeight(0) 37 , fHaveCalledOnceBeforeDraw(false) 38 {} 39 width()40 SkScalar width() const { return fWidth; } height()41 SkScalar height() const { return fHeight; } 42 void setSize(SkScalar width, SkScalar height); setSize(const SkPoint & size)43 void setSize(const SkPoint& size) { this->setSize(size.fX, size.fY); } setWidth(SkScalar width)44 void setWidth(SkScalar width) { this->setSize(width, fHeight); } setHeight(SkScalar height)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 setBGColor(SkColor color)83 void setBGColor(SkColor color) { fBGColor = color; } animate(const SkAnimTimer & timer)84 bool animate(const SkAnimTimer& timer) { return this->onAnimate(timer); } 85 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 */ getFast32()97 uint32_t getFast32() const { return f32; } 98 99 /** Set the event's unnamed 32bit field. */ setFast32(uint32_t x)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. */ findString(const char name[])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 */ findPtr(const char name[],void ** value)130 bool findPtr(const char name[], void** value) const { return fMeta.findPtr(name, value); } findBool(const char name[],bool * 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 */ hasS32(const char name[],int32_t 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 */ hasScalar(const char name[],SkScalar 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 */ hasString(const char name[],const char 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 */ hasPtr(const char name[],void * value)143 bool hasPtr(const char name[], void* value) const { return fMeta.hasPtr(name, value); } hasBool(const char name[],bool value)144 bool hasBool(const char name[], bool value) const { return fMeta.hasBool(name, value); } hasData(const char name[],const void * data,size_t byteCount)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. */ setS32(const char name[],int32_t value)150 void setS32(const char name[], int32_t value) { fMeta.setS32(name, value); } 151 /** Add/replace the named SkScalar field to the event. */ setScalar(const char name[],SkScalar value)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. */ setString(const char name[],const char value[])158 void setString(const char name[], const char value[]) { fMeta.setString(name, value); } 159 /** Add/replace the named pointer field to the event. */ setPtr(const char name[],void * value)160 void setPtr(const char name[], void* value) { fMeta.setPtr(name, value); } setBool(const char name[],bool value)161 void setBool(const char name[], bool value) { fMeta.setBool(name, value); } setData(const char name[],const void * data,size_t byteCount)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 */ getMetaData()167 SkMetaData& getMetaData() { return fMeta; } 168 /** Return the underlying metadata object */ getMetaData()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 194 protected: 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; onAnimate(const SkAnimTimer &)212 virtual bool onAnimate(const SkAnimTimer&) { return false; } onOnceBeforeDraw()213 virtual void onOnceBeforeDraw() {} 214 215 private: 216 SkColor fBGColor; 217 SkScalar fWidth, fHeight; 218 bool fHaveCalledOnceBeforeDraw; 219 }; 220 221 #endif 222