コード例 #1
0
//static
void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t& registry, LLXMLNodePtr output_node)
{
    LLFastTimer ft(FTM_CREATE_CHILDREN);
    if (node.isNull()) return;

    for (LLXMLNodePtr child_node = node->getFirstChild(); child_node.notNull(); child_node = child_node->getNextSibling())
    {
        LLXMLNodePtr outputChild;
        if (output_node)
        {
            outputChild = output_node->createChild("", FALSE);
        }

        if (!instance().createFromXML(child_node, viewp, LLStringUtil::null, registry, outputChild))
        {
            // child_node is not a valid child for the current parent
            std::string child_name = std::string(child_node->getName()->mString);
            if (LLDefaultChildRegistry::instance().getValue(child_name))
            {
                // This means that the registry assocaited with the parent widget does not have an entry
                // for the child widget
                // You might need to add something like:
                // static ParentWidgetRegistry::Register<ChildWidgetType> register("child_widget_name");
                llwarns << child_name << " is not a valid child of " << node->getName()->mString << llendl;
            }
            else
            {
                llwarns << "Could not create widget named " << child_node->getName()->mString << llendl;
            }
        }

        if (outputChild && !outputChild->mChildren && outputChild->mAttributes.empty() && outputChild->getValue().empty())
        {
            output_node->deleteChild(outputChild);
        }
    }

}
コード例 #2
0
ファイル: llxuiparser.cpp プロジェクト: HyangZhao/NaCl-main
bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLInitParam::BaseBlock& block)
{
	typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
	boost::char_separator<char> sep(".");

	bool values_parsed = false;

	// submit attributes for current node
	values_parsed |= readAttributes(nodep, block);

	// treat text contents of xml node as "value" parameter
	std::string text_contents = nodep->getSanitizedValue();
	if (!text_contents.empty())
	{
		mCurReadNode = nodep;
		mNameStack.push_back(std::make_pair(std::string("value"), newParseGeneration()));
		// child nodes are not necessarily valid parameters (could be a child widget)
		// so don't complain once we've recursed
		bool silent = mCurReadDepth > 0;
		if (!block.submitValue(mNameStack, *this, true))
		{
			mNameStack.pop_back();
			block.submitValue(mNameStack, *this, silent);
		}
		else
		{
			mNameStack.pop_back();
		}
	}

	// then traverse children
	// child node must start with last name of parent node (our "scope")
	// for example: "<button><button.param nested_param1="foo"><param.nested_param2 nested_param3="bar"/></button.param></button>"
	// which equates to the following nesting:
	// button
	//     param
	//         nested_param1
	//         nested_param2
	//             nested_param3	
	mCurReadDepth++;
	for(LLXMLNodePtr childp = nodep->getFirstChild(); childp.notNull();)
	{
		std::string child_name(childp->getName()->mString);
		S32 num_tokens_pushed = 0;

		// for non "dotted" child nodes	check to see if child node maps to another widget type
		// and if not, treat as a child element of the current node
		// e.g. <button><rect left="10"/></button> will interpret <rect> as "button.rect"
		// since there is no widget named "rect"
		if (child_name.find(".") == std::string::npos) 
		{
			mNameStack.push_back(std::make_pair(child_name, newParseGeneration()));
			num_tokens_pushed++;
		}
		else
		{
			// parse out "dotted" name into individual tokens
			tokenizer name_tokens(child_name, sep);

			tokenizer::iterator name_token_it = name_tokens.begin();
			if(name_token_it == name_tokens.end()) 
			{
				childp = childp->getNextSibling();
				continue;
			}

			// check for proper nesting
			if(!scope.empty() && *name_token_it != scope)
			{
				childp = childp->getNextSibling();
				continue;
			}

			// now ignore first token
			++name_token_it; 

			// copy remaining tokens on to our running token list
			for(tokenizer::iterator token_to_push = name_token_it; token_to_push != name_tokens.end(); ++token_to_push)
			{
				mNameStack.push_back(std::make_pair(*token_to_push, newParseGeneration()));
				num_tokens_pushed++;
			}
		}

		// recurse and visit children XML nodes
		if(readXUIImpl(childp, mNameStack.empty() ? scope : mNameStack.back().first, block))
		{
			// child node successfully parsed, remove from DOM

			values_parsed = true;
			LLXMLNodePtr node_to_remove = childp;
			childp = childp->getNextSibling();

			nodep->deleteChild(node_to_remove);
		}
		else
		{
			childp = childp->getNextSibling();
		}

		while(num_tokens_pushed-- > 0)
		{
			mNameStack.pop_back();
		}
	}
	mCurReadDepth--;
	return values_parsed;
}