Home | History | Annotate | Download | only in views
      1 #include "SkViewInflate.h"
      2 #include "SkView.h"
      3 #include <stdio.h>
      4 
      5 SkViewInflate::SkViewInflate() : fIDs(kMinIDStrAlloc), fStrings(kMinIDStrAlloc)
      6 {
      7 }
      8 
      9 SkViewInflate::~SkViewInflate()
     10 {
     11 }
     12 
     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 
     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 
     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 
     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 
    102 SkView* SkViewInflate::findViewByID(const char id[]) const
    103 {
    104 	SkASSERT(id);
    105 	SkView* view;
    106 	return fIDs.find(id, &view) ? view : NULL;
    107 }
    108 
    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 
    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
    126 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