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