OLD | NEW |
| (Empty) |
1 | |
2 /* | |
3 * Copyright 2011 Google Inc. | |
4 * | |
5 * Use of this source code is governed by a BSD-style license that can be | |
6 * found in the LICENSE file. | |
7 */ | |
8 #include "SkWidgetViews.h" | |
9 #include "SkAnimator.h" | |
10 #include "SkCanvas.h" | |
11 #include "SkPaint.h" | |
12 #include "SkStream.h" | |
13 #include "SkSystemEventTypes.h" | |
14 | |
15 /* | |
16 I have moved this to SkWidgetViews.h | |
17 enum SkinEnum { | |
18 kButton_SkinEnum, | |
19 kProgress_SkinEnum, | |
20 kScroll_SkinEnum, | |
21 kStaticText_SkinEnum, | |
22 | |
23 kSkinEnumCount | |
24 }; | |
25 */ | |
26 | |
27 const char* get_skin_enum_path(SkinEnum se) | |
28 { | |
29 SkASSERT((unsigned)se < kSkinEnumCount); | |
30 | |
31 static const char* gSkinPaths[] = { | |
32 "common/default/default/skins/border3.xml", | |
33 "common/default/default/skins/button.xml", | |
34 "common/default/default/skins/progressBar.xml", | |
35 "common/default/default/skins/scrollBar.xml", | |
36 "common/default/default/skins/statictextpaint.xml" | |
37 }; | |
38 | |
39 return gSkinPaths[se]; | |
40 } | |
41 | |
42 void init_skin_anim(const char path[], SkAnimator* anim) { | |
43 SkASSERT(path && anim); | |
44 | |
45 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path)); | |
46 if (!stream.get()) { | |
47 SkDEBUGF(("init_skin_anim: loading skin failed <%s>\n", path)); | |
48 sk_throw(); | |
49 } | |
50 | |
51 if (!anim->decodeStream(stream)) { | |
52 SkDEBUGF(("init_skin_anim: decoding skin failed <%s>\n", path)); | |
53 sk_throw(); | |
54 } | |
55 } | |
56 | |
57 void init_skin_anim(SkinEnum se, SkAnimator* anim) | |
58 { | |
59 init_skin_anim(get_skin_enum_path(se), anim); | |
60 } | |
61 | |
62 void init_skin_paint(SkinEnum se, SkPaint* paint) | |
63 { | |
64 SkASSERT(paint); | |
65 | |
66 SkAnimator anim; | |
67 SkCanvas canvas; | |
68 | |
69 init_skin_anim(se, &anim); | |
70 anim.draw(&canvas, paint, 0); | |
71 } | |
72 | |
73 void inflate_paint(const SkDOM& dom, const SkDOM::Node* node, SkPaint* paint) | |
74 { | |
75 SkASSERT(paint); | |
76 | |
77 SkAnimator anim; | |
78 SkCanvas canvas; | |
79 | |
80 if (!anim.decodeDOM(dom, node)) | |
81 { | |
82 SkDEBUGF(("inflate_paint: decoding dom failed\n")); | |
83 SkDEBUGCODE(dom.dump(node);) | |
84 sk_throw(); | |
85 } | |
86 anim.draw(&canvas, paint, 0); | |
87 } | |
88 | |
89 ////////////////////////////////////////////////////////////////////////////////
//////// | |
90 | |
91 SkWidgetView::SkWidgetView() : SkView(SkView::kFocusable_Mask | SkView::kEnabled
_Mask) | |
92 { | |
93 } | |
94 | |
95 const char* SkWidgetView::getLabel() const | |
96 { | |
97 return fLabel.c_str(); | |
98 } | |
99 | |
100 void SkWidgetView::getLabel(SkString* label) const | |
101 { | |
102 if (label) | |
103 *label = fLabel; | |
104 } | |
105 | |
106 void SkWidgetView::setLabel(const char label[]) | |
107 { | |
108 this->setLabel(label, label ? strlen(label) : 0); | |
109 } | |
110 | |
111 void SkWidgetView::setLabel(const char label[], size_t len) | |
112 { | |
113 if ((label == nullptr && fLabel.size() != 0) || !fLabel.equals(label, len)) | |
114 { | |
115 SkString tmp(label, len); | |
116 | |
117 this->onLabelChange(fLabel.c_str(), tmp.c_str()); | |
118 fLabel.swap(tmp); | |
119 } | |
120 } | |
121 | |
122 void SkWidgetView::setLabel(const SkString& label) | |
123 { | |
124 if (fLabel != label) | |
125 { | |
126 this->onLabelChange(fLabel.c_str(), label.c_str()); | |
127 fLabel = label; | |
128 } | |
129 } | |
130 | |
131 bool SkWidgetView::postWidgetEvent() | |
132 { | |
133 if (!fEvent.isType("")) | |
134 { | |
135 SkEvent evt(fEvent); // make a copy since onPrepareWidgetEvent may
edit the event | |
136 | |
137 if (this->onPrepareWidgetEvent(&evt)) | |
138 { | |
139 SkDEBUGCODE(evt.dump("SkWidgetView::postWidgetEvent");) | |
140 | |
141 this->postToListeners(evt); // wonder if this should return true
if there are > 0 listeners... | |
142 return true; | |
143 } | |
144 } | |
145 return false; | |
146 } | |
147 | |
148 /*virtual*/ void SkWidgetView::onInflate(const SkDOM& dom, const SkDOM::Node* no
de) | |
149 { | |
150 this->INHERITED::onInflate(dom, node); | |
151 | |
152 const char* label = dom.findAttr(node, "label"); | |
153 if (label) | |
154 this->setLabel(label); | |
155 | |
156 if ((node = dom.getFirstChild(node, "event")) != nullptr) | |
157 fEvent.inflate(dom, node); | |
158 } | |
159 | |
160 /*virtual*/ void SkWidgetView::onLabelChange(const char oldLabel[], const char n
ewLabel[]) | |
161 { | |
162 this->inval(nullptr); | |
163 } | |
164 | |
165 static const char gWidgetEventSinkIDSlotName[] = "sk-widget-sinkid-slot"; | |
166 | |
167 /*virtual*/ bool SkWidgetView::onPrepareWidgetEvent(SkEvent* evt) | |
168 { | |
169 evt->setS32(gWidgetEventSinkIDSlotName, this->getSinkID()); | |
170 return true; | |
171 } | |
172 | |
173 SkEventSinkID SkWidgetView::GetWidgetEventSinkID(const SkEvent& evt) | |
174 { | |
175 int32_t sinkID; | |
176 | |
177 return evt.findS32(gWidgetEventSinkIDSlotName, &sinkID) ? (SkEventSinkID)sin
kID : 0; | |
178 } | |
179 | |
180 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | |
181 | |
182 /*virtual*/ bool SkButtonView::onEvent(const SkEvent& evt) | |
183 { | |
184 if (evt.isType(SK_EventType_Key) && evt.getFast32() == kOK_SkKey) | |
185 { | |
186 this->postWidgetEvent(); | |
187 return true; | |
188 } | |
189 return this->INHERITED::onEvent(evt); | |
190 } | |
191 | |
192 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | |
193 | |
194 SkCheckButtonView::SkCheckButtonView() : fCheckState(kOff_CheckState) | |
195 { | |
196 } | |
197 | |
198 void SkCheckButtonView::setCheckState(CheckState state) | |
199 { | |
200 SkASSERT((unsigned)state <= kUnknown_CheckState); | |
201 | |
202 if (fCheckState != state) | |
203 { | |
204 this->onCheckStateChange(this->getCheckState(), state); | |
205 fCheckState = SkToU8(state); | |
206 } | |
207 } | |
208 | |
209 /*virtual*/ void SkCheckButtonView::onCheckStateChange(CheckState oldState, Chec
kState newState) | |
210 { | |
211 this->inval(nullptr); | |
212 } | |
213 | |
214 /*virtual*/ void SkCheckButtonView::onInflate(const SkDOM& dom, const SkDOM::Nod
e* node) | |
215 { | |
216 this->INHERITED::onInflate(dom, node); | |
217 | |
218 int index = dom.findList(node, "check-state", "off,on,unknown"); | |
219 if (index >= 0) | |
220 this->setCheckState((CheckState)index); | |
221 } | |
222 | |
223 static const char gCheckStateSlotName[] = "sk-checkbutton-check-slot"; | |
224 | |
225 /*virtual*/ bool SkCheckButtonView::onPrepareWidgetEvent(SkEvent* evt) | |
226 { | |
227 // could check if we're "disabled", and return false... | |
228 | |
229 evt->setS32(gCheckStateSlotName, this->getCheckState()); | |
230 return true; | |
231 } | |
232 | |
233 bool SkCheckButtonView::GetWidgetEventCheckState(const SkEvent& evt, CheckState*
state) | |
234 { | |
235 int32_t state32; | |
236 | |
237 if (evt.findS32(gCheckStateSlotName, &state32)) | |
238 { | |
239 if (state) | |
240 *state = (CheckState)state32; | |
241 return true; | |
242 } | |
243 return false; | |
244 } | |
245 | |
246 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | |
247 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | |
248 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | |
249 | |
250 #include "SkTime.h" | |
251 #include <stdio.h> | |
252 | |
253 class SkAnimButtonView : public SkButtonView { | |
254 public: | |
255 SkAnimButtonView() | |
256 { | |
257 fAnim.setHostEventSink(this); | |
258 init_skin_anim(kButton_SkinEnum, &fAnim); | |
259 } | |
260 | |
261 protected: | |
262 virtual void onLabelChange(const char oldLabel[], const char newLabel[]) | |
263 { | |
264 this->INHERITED::onLabelChange(oldLabel, newLabel); | |
265 | |
266 SkEvent evt("user"); | |
267 evt.setString("id", "setLabel"); | |
268 evt.setString("LABEL", newLabel); | |
269 fAnim.doUserEvent(evt); | |
270 } | |
271 | |
272 virtual void onFocusChange(bool gainFocus) | |
273 { | |
274 this->INHERITED::onFocusChange(gainFocus); | |
275 | |
276 SkEvent evt("user"); | |
277 evt.setString("id", "setFocus"); | |
278 evt.setS32("FOCUS", gainFocus); | |
279 fAnim.doUserEvent(evt); | |
280 } | |
281 | |
282 virtual void onSizeChange() | |
283 { | |
284 this->INHERITED::onSizeChange(); | |
285 | |
286 SkEvent evt("user"); | |
287 evt.setString("id", "setDim"); | |
288 evt.setScalar("dimX", this->width()); | |
289 evt.setScalar("dimY", this->height()); | |
290 fAnim.doUserEvent(evt); | |
291 } | |
292 | |
293 virtual void onDraw(SkCanvas* canvas) | |
294 { | |
295 SkPaint paint; | |
296 SkAnimator::DifferenceType diff = fAnim.draw(canvas, &paint, SkTime::
GetMSecs()); | |
297 | |
298 if (diff == SkAnimator::kDifferent) | |
299 this->inval(nullptr); | |
300 else if (diff == SkAnimator::kPartiallyDifferent) | |
301 { | |
302 SkRect bounds; | |
303 fAnim.getInvalBounds(&bounds); | |
304 this->inval(&bounds); | |
305 } | |
306 } | |
307 | |
308 virtual bool onEvent(const SkEvent& evt) | |
309 { | |
310 if (evt.isType(SK_EventType_Inval)) | |
311 { | |
312 this->inval(nullptr); | |
313 return true; | |
314 } | |
315 if (evt.isType("recommendDim")) | |
316 { | |
317 SkScalar height; | |
318 | |
319 if (evt.findScalar("y", &height)) | |
320 this->setHeight(height); | |
321 return true; | |
322 } | |
323 return this->INHERITED::onEvent(evt); | |
324 } | |
325 | |
326 virtual bool onPrepareWidgetEvent(SkEvent* evt) | |
327 { | |
328 if (this->INHERITED::onPrepareWidgetEvent(evt)) | |
329 { | |
330 SkEvent e("user"); | |
331 e.setString("id", "handlePress"); | |
332 (void)fAnim.doUserEvent(e); | |
333 return true; | |
334 } | |
335 return false; | |
336 } | |
337 | |
338 private: | |
339 SkAnimator fAnim; | |
340 | |
341 typedef SkButtonView INHERITED; | |
342 }; | |
343 | |
344 ////////////////////////////////////////////////////////////////////////////////
//////////// | |
345 ////////////////////////////////////////////////////////////////////////////////
//////////// | |
346 | |
347 SkView* SkWidgetFactory(const char name[]) | |
348 { | |
349 if (name == nullptr) | |
350 return nullptr; | |
351 | |
352 // must be in the same order as the SkSkinWidgetEnum is declared | |
353 static const char* gNames[] = { | |
354 "sk-border", | |
355 "sk-button", | |
356 "sk-image", | |
357 "sk-list", | |
358 "sk-progress", | |
359 "sk-scroll", | |
360 "sk-text" | |
361 | |
362 }; | |
363 | |
364 for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); i++) | |
365 if (!strcmp(gNames[i], name)) | |
366 return SkWidgetFactory((SkWidgetEnum)i); | |
367 | |
368 return nullptr; | |
369 } | |
370 | |
371 #include "SkImageView.h" | |
372 #include "SkProgressBarView.h" | |
373 #include "SkScrollBarView.h" | |
374 #include "SkBorderView.h" | |
375 | |
376 SkView* SkWidgetFactory(SkWidgetEnum sw) | |
377 { | |
378 switch (sw) { | |
379 case kBorder_WidgetEnum: | |
380 return new SkBorderView; | |
381 case kButton_WidgetEnum: | |
382 return new SkAnimButtonView; | |
383 case kImage_WidgetEnum: | |
384 return new SkImageView; | |
385 case kList_WidgetEnum: | |
386 return new SkListView; | |
387 case kProgress_WidgetEnum: | |
388 return new SkProgressBarView; | |
389 case kScroll_WidgetEnum: | |
390 return new SkScrollBarView; | |
391 case kText_WidgetEnum: | |
392 return new SkStaticTextView; | |
393 default: | |
394 SkDEBUGFAIL("unknown enum passed to SkWidgetFactory"); | |
395 break; | |
396 } | |
397 return nullptr; | |
398 } | |
OLD | NEW |