• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "SkViewInflate.h"
2 #include "SkView.h"
3 #include <stdio.h>
4 
SkViewInflate()5 SkViewInflate::SkViewInflate() : fIDs(kMinIDStrAlloc), fStrings(kMinIDStrAlloc)
6 {
7 }
8 
~SkViewInflate()9 SkViewInflate::~SkViewInflate()
10 {
11 }
12 
rInflate(const SkDOM & dom,const SkDOM::Node * node,SkView * parent)13 void SkViewInflate::rInflate(const SkDOM& dom, const SkDOM::Node* node, SkView* parent)
14 {
15 	const char* str = dom.findAttr(node, "id");
16 	if (str)
17 		fIDs.set(str, parent);
18 
19 	const SkDOM::Node* child = dom.getFirstChild(node);
20 	while (child)
21 	{
22 		SkView* view = this->createView(dom, child);
23 		if (view)
24 		{
25 			this->rInflate(dom, child, view);
26 			parent->attachChildToFront(view)->unref();
27 		}
28 		else
29 		{
30 			const char* name = dom.getName(child);
31 			const char* target;
32 
33 			if (!strcmp(name, "listenTo") && (target = dom.findAttr(child, "target")) != NULL)
34 				this->addIDStr(&fListenTo, parent, target);
35 
36 			if (!strcmp(name, "broadcastTo") && (target = dom.findAttr(child, "target")) != NULL)
37 				this->addIDStr(&fBroadcastTo, parent, target);
38 		}
39 		child = dom.getNextSibling(child);
40 	}
41 
42 	parent->setVisibleP(true);
43 	this->inflateView(parent, dom, node);
44 }
45 
inflateView(SkView * view,const SkDOM & dom,const SkDOM::Node * node)46 void SkViewInflate::inflateView(SkView* view, const SkDOM& dom, const SkDOM::Node* node)
47 {
48 	// called after all of view's children have been instantiated.
49 	// this may be overridden by a subclass, to load in layout or other helpers
50 	// they should call through to us (INHERITED) before or after their patch
51 	view->inflate(dom, node);
52 }
53 
inflate(const SkDOM & dom,const SkDOM::Node * node,SkView * root)54 SkView* SkViewInflate::inflate(const SkDOM& dom, const SkDOM::Node* node, SkView* root)
55 {
56 	fIDs.reset();
57 
58 	if (root == NULL)
59 	{
60 		root = this->createView(dom, node);
61 		if (root == NULL)
62 		{
63 			printf("createView returned NULL on <%s>\n", dom.getName(node));
64 			return NULL;
65 		}
66 	}
67 	this->rInflate(dom, node, root);
68 
69 	// resolve listeners and broadcasters
70 	{
71 		SkView*			target;
72 		const IDStr*	iter = fListenTo.begin();
73 		const IDStr*	stop = fListenTo.end();
74 		for (; iter < stop; iter++)
75 		{
76 			if (fIDs.find(iter->fStr, &target))
77 				target->addListenerID(iter->fView->getSinkID());
78 		}
79 
80 		iter = fBroadcastTo.begin();
81 		stop = fBroadcastTo.end();
82 		for (; iter < stop; iter++)
83 		{
84 			if (fIDs.find(iter->fStr, &target))
85 				iter->fView->addListenerID(target->getSinkID());
86 		}
87 	}
88 
89 	// now that the tree is built, give everyone a shot at the ID dict
90 	root->postInflate(fIDs);
91 	return root;
92 }
93 
inflate(const char xml[],size_t len,SkView * root)94 SkView* SkViewInflate::inflate(const char xml[], size_t len, SkView* root)
95 {
96 	SkDOM				dom;
97 	const SkDOM::Node*	node = dom.build(xml, len);
98 
99 	return node ? this->inflate(dom, node, root) : NULL;
100 }
101 
findViewByID(const char id[]) const102 SkView* SkViewInflate::findViewByID(const char id[]) const
103 {
104 	SkASSERT(id);
105 	SkView* view;
106 	return fIDs.find(id, &view) ? view : NULL;
107 }
108 
createView(const SkDOM & dom,const SkDOM::Node * node)109 SkView* SkViewInflate::createView(const SkDOM& dom, const SkDOM::Node* node)
110 {
111 	if (!strcmp(dom.getName(node), "view"))
112 		return new SkView;
113 	return NULL;
114 }
115 
addIDStr(SkTDArray<IDStr> * list,SkView * view,const char * str)116 void SkViewInflate::addIDStr(SkTDArray<IDStr>* list, SkView* view, const char* str)
117 {
118 	size_t len = strlen(str) + 1;
119 	IDStr* pair = list->append();
120 	pair->fView = view;
121 	pair->fStr = (char*)fStrings.alloc(len, SkChunkAlloc::kThrow_AllocFailType);
122 	memcpy(pair->fStr, str, len);
123 }
124 
125 #ifdef SK_DEBUG
dump() const126 void SkViewInflate::dump() const
127 {
128 	const IDStr* iter = fListenTo.begin();
129 	const IDStr* stop = fListenTo.end();
130 	for (; iter < stop; iter++)
131 		SkDebugf("inflate: listenTo(\"%s\")\n", iter->fStr);
132 
133 	iter = fBroadcastTo.begin();
134 	stop = fBroadcastTo.end();
135 	for (; iter < stop; iter++)
136 		SkDebugf("inflate: broadcastFrom(\"%s\")\n", iter->fStr);
137 }
138 #endif
139 
140