1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/views/SkViewInflate.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,145 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2011 Google Inc. 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 +#include "SkViewInflate.h" 1.12 +#include "SkView.h" 1.13 +#include <stdio.h> 1.14 + 1.15 +SkViewInflate::SkViewInflate() : fIDs(kMinIDStrAlloc), fStrings(kMinIDStrAlloc) 1.16 +{ 1.17 +} 1.18 + 1.19 +SkViewInflate::~SkViewInflate() 1.20 +{ 1.21 +} 1.22 + 1.23 +void SkViewInflate::rInflate(const SkDOM& dom, const SkDOM::Node* node, SkView* parent) 1.24 +{ 1.25 + const char* str = dom.findAttr(node, "id"); 1.26 + if (str) 1.27 + fIDs.set(str, parent); 1.28 + 1.29 + const SkDOM::Node* child = dom.getFirstChild(node); 1.30 + while (child) 1.31 + { 1.32 + SkView* view = this->createView(dom, child); 1.33 + if (view) 1.34 + { 1.35 + this->rInflate(dom, child, view); 1.36 + parent->attachChildToFront(view)->unref(); 1.37 + } 1.38 + else 1.39 + { 1.40 + const char* name = dom.getName(child); 1.41 + const char* target; 1.42 + 1.43 + if (!strcmp(name, "listenTo") && (target = dom.findAttr(child, "target")) != NULL) 1.44 + this->addIDStr(&fListenTo, parent, target); 1.45 + 1.46 + if (!strcmp(name, "broadcastTo") && (target = dom.findAttr(child, "target")) != NULL) 1.47 + this->addIDStr(&fBroadcastTo, parent, target); 1.48 + } 1.49 + child = dom.getNextSibling(child); 1.50 + } 1.51 + 1.52 + parent->setVisibleP(true); 1.53 + this->inflateView(parent, dom, node); 1.54 +} 1.55 + 1.56 +void SkViewInflate::inflateView(SkView* view, const SkDOM& dom, const SkDOM::Node* node) 1.57 +{ 1.58 + // called after all of view's children have been instantiated. 1.59 + // this may be overridden by a subclass, to load in layout or other helpers 1.60 + // they should call through to us (INHERITED) before or after their patch 1.61 + view->inflate(dom, node); 1.62 +} 1.63 + 1.64 +SkView* SkViewInflate::inflate(const SkDOM& dom, const SkDOM::Node* node, SkView* root) 1.65 +{ 1.66 + fIDs.reset(); 1.67 + 1.68 + if (root == NULL) 1.69 + { 1.70 + root = this->createView(dom, node); 1.71 + if (root == NULL) 1.72 + { 1.73 + printf("createView returned NULL on <%s>\n", dom.getName(node)); 1.74 + return NULL; 1.75 + } 1.76 + } 1.77 + this->rInflate(dom, node, root); 1.78 + 1.79 + // resolve listeners and broadcasters 1.80 + { 1.81 + SkView* target; 1.82 + const IDStr* iter = fListenTo.begin(); 1.83 + const IDStr* stop = fListenTo.end(); 1.84 + for (; iter < stop; iter++) 1.85 + { 1.86 + if (fIDs.find(iter->fStr, &target)) 1.87 + target->addListenerID(iter->fView->getSinkID()); 1.88 + } 1.89 + 1.90 + iter = fBroadcastTo.begin(); 1.91 + stop = fBroadcastTo.end(); 1.92 + for (; iter < stop; iter++) 1.93 + { 1.94 + if (fIDs.find(iter->fStr, &target)) 1.95 + iter->fView->addListenerID(target->getSinkID()); 1.96 + } 1.97 + } 1.98 + 1.99 + // now that the tree is built, give everyone a shot at the ID dict 1.100 + root->postInflate(fIDs); 1.101 + return root; 1.102 +} 1.103 + 1.104 +SkView* SkViewInflate::inflate(const char xml[], size_t len, SkView* root) 1.105 +{ 1.106 + SkDOM dom; 1.107 + const SkDOM::Node* node = dom.build(xml, len); 1.108 + 1.109 + return node ? this->inflate(dom, node, root) : NULL; 1.110 +} 1.111 + 1.112 +SkView* SkViewInflate::findViewByID(const char id[]) const 1.113 +{ 1.114 + SkASSERT(id); 1.115 + SkView* view; 1.116 + return fIDs.find(id, &view) ? view : NULL; 1.117 +} 1.118 + 1.119 +SkView* SkViewInflate::createView(const SkDOM& dom, const SkDOM::Node* node) 1.120 +{ 1.121 + if (!strcmp(dom.getName(node), "view")) 1.122 + return new SkView; 1.123 + return NULL; 1.124 +} 1.125 + 1.126 +void SkViewInflate::addIDStr(SkTDArray<IDStr>* list, SkView* view, const char* str) 1.127 +{ 1.128 + size_t len = strlen(str) + 1; 1.129 + IDStr* pair = list->append(); 1.130 + pair->fView = view; 1.131 + pair->fStr = (char*)fStrings.alloc(len, SkChunkAlloc::kThrow_AllocFailType); 1.132 + memcpy(pair->fStr, str, len); 1.133 +} 1.134 + 1.135 +#ifdef SK_DEBUG 1.136 +void SkViewInflate::dump() const 1.137 +{ 1.138 + const IDStr* iter = fListenTo.begin(); 1.139 + const IDStr* stop = fListenTo.end(); 1.140 + for (; iter < stop; iter++) 1.141 + SkDebugf("inflate: listenTo(\"%s\")\n", iter->fStr); 1.142 + 1.143 + iter = fBroadcastTo.begin(); 1.144 + stop = fBroadcastTo.end(); 1.145 + for (; iter < stop; iter++) 1.146 + SkDebugf("inflate: broadcastFrom(\"%s\")\n", iter->fStr); 1.147 +} 1.148 +#endif