Beispiel #1
0
/**
 * @brief Clone a node
 * @param[in] node Node to clone
 * @param[in] recursive True if we also must clone subnodes
 * @param[in] newWindow Window where the nodes must be add (this function only link node into window, not window into the new node)
 * @param[in] newName New node name, else nullptr to use the source name
 * @param[in] isDynamic Allocate a node in static or dynamic memory
 * @todo exclude rect is not safe cloned.
 * @todo actions are not cloned. It is be a problem if we use add/remove listener into a cloned node.
 */
uiNode_t* UI_CloneNode (const uiNode_t* node, uiNode_t* newWindow, bool recursive, const char* newName, bool isDynamic)
{
	uiNode_t* newNode = UI_AllocNodeWithoutNew(nullptr, UI_Node_GetWidgetName(node), isDynamic);

	/* clone all data */
	memcpy(newNode, node, UI_Node_GetMemorySize(node));
	newNode->dynamic = isDynamic;

	/* custom name */
	if (newName != nullptr) {
		Q_strncpyz(newNode->name, newName, sizeof(newNode->name));
		if (strlen(newNode->name) != strlen(newName))
			Com_Printf("UI_CloneNode: Node name \"%s\" truncated. New name is \"%s\"\n", newName, newNode->name);
	}

	/* clean up node navigation */
	if (node->root == node && newWindow == nullptr)
		newWindow = newNode;

	newNode->root = newWindow;
	newNode->parent = nullptr;
	newNode->firstChild = nullptr;
	newNode->lastChild = nullptr;
	newNode->next = nullptr;
	newNode->super = node;

	/* clone node methods */
	if (node->nodeMethods) {
		newNode->nodeMethods = HASH_CloneTable(node->nodeMethods);
	}

	/* allocate memories */
	if (newNode->dynamic) {
		UI_Node_InitNodeDynamic(newNode);
	}

	/* typically, cloning makes a copy of all the internals of a source node; override the ::clone(node) method
	   to alter this behaviour */
	UI_Node_Clone(node, newNode);

	/* clone child */
	if (recursive) {
		for (uiNode_t* childNode = node->firstChild; childNode; childNode = childNode->next) {
			uiNode_t* newChildNode = UI_CloneNode(childNode, newWindow, recursive, nullptr, isDynamic);
			UI_AppendNode(newNode, newChildNode);
		}
	}

	return newNode;
}
Beispiel #2
0
/**
 * @brief Clone a node
 * @param[in] node Node to clone
 * @param[in] recursive True if we also must clone subnodes
 * @param[in] newWindow Window where the nodes must be add (this function only link node into window, not window into the new node)
 * @param[in] newName New node name, else nullptr to use the source name
 * @param[in] isDynamic Allocate a node in static or dynamic memory
 * @todo exclude rect is not safe cloned.
 * @todo actions are not cloned. It is be a problem if we use add/remove listener into a cloned node.
 */
uiNode_t* UI_CloneNode (const uiNode_t* node, uiNode_t *newWindow, bool recursive, const char *newName, bool isDynamic)
{
	uiNode_t* newNode = UI_AllocNodeWithoutNew(nullptr, UI_Node_GetWidgetName(node), isDynamic);

	/* clone all data */
	memcpy(newNode, node, UI_Node_GetMemorySize(node));
	newNode->dynamic = isDynamic;

	/* custom name */
	if (newName != nullptr) {
		Q_strncpyz(newNode->name, newName, sizeof(newNode->name));
		if (strlen(newNode->name) != strlen(newName))
			Com_Printf("UI_CloneNode: Node name \"%s\" truncated. New name is \"%s\"\n", newName, newNode->name);
	}

	/* clean up node navigation */
	if (node->root == node && newWindow == nullptr)
		newWindow = newNode;
	newNode->root = newWindow;
	newNode->parent = nullptr;
	newNode->firstChild = nullptr;
	newNode->lastChild = nullptr;
	newNode->next = nullptr;
	newNode->super = node;

	/* clone child */
	if (recursive) {
		uiNode_t* childNode;
		for (childNode = node->firstChild; childNode; childNode = childNode->next) {
			uiNode_t* newChildNode = UI_CloneNode(childNode, newWindow, recursive, nullptr, isDynamic);
			UI_AppendNode(newNode, newChildNode);
		}
	}

	/* allocate memories */
	if (newNode->dynamic)
		UI_Node_NewNode(newNode);

	UI_Node_Clone(node, newNode);

	return newNode;
}