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