Beispiel #1
0
/**
 * @brief Return the first visible node at a position
 * @param[in] node Node where we must search
 * @param[in] rx Relative x position to the parent of the node
 * @param[in] ry Relative y position to the parent of the node
 * @return The first visible node at position, else NULL
 */
static uiNode_t *UI_GetNodeInTreeAtPosition (uiNode_t *node, int rx, int ry)
{
	uiNode_t *find;

	if (node->invis || node->behaviour->isVirtual || !UI_CheckVisibility(node))
		return NULL;

	/* relative to the node */
	rx -= node->pos[0];
	ry -= node->pos[1];

	/* check bounding box */
	if (rx < 0 || ry < 0 || rx >= node->size[0] || ry >= node->size[1])
		return NULL;

	/** @todo we should improve the loop (last-to-first) */
	find = NULL;
	if (node->firstChild) {
		uiNode_t *child;
		vec2_t clientPosition = {0, 0};

		if (node->behaviour->getClientPosition)
			node->behaviour->getClientPosition(node, clientPosition);

		rx -= clientPosition[0];
		ry -= clientPosition[1];

		for (child = node->firstChild; child; child = child->next) {
			uiNode_t *tmp;
			tmp = UI_GetNodeInTreeAtPosition(child, rx, ry);
			if (tmp)
				find = tmp;
		}

		rx += clientPosition[0];
		ry += clientPosition[1];
	}
	if (find)
		return find;

	/* disable ghost/excluderect in debug mode 2 */
	if (UI_DebugMode() != 2) {
		int i;
		/* is the node tangible */
		if (node->ghost)
			return NULL;

		/* check excluded box */
		for (i = 0; i < node->excludeRectNum; i++) {
			if (rx >= node->excludeRect[i].pos[0]
			 && rx < node->excludeRect[i].pos[0] + node->excludeRect[i].size[0]
			 && ry >= node->excludeRect[i].pos[1]
			 && ry < node->excludeRect[i].pos[1] + node->excludeRect[i].size[1])
				return NULL;
		}
	}

	/* we are over the node */
	return node;
}
Beispiel #2
0
/**
 * @brief Return the first visible node at a position
 * @param[in] node Node where we must search
 * @param[in] rx Relative x position to the parent of the node
 * @param[in] ry Relative y position to the parent of the node
 * @return The first visible node at position, else nullptr
 */
static uiNode_t *UI_GetNodeInTreeAtPosition (uiNode_t *node, int rx, int ry)
{
	uiNode_t *find;

	if (node->invis || UI_Node_IsVirtual(node) || !UI_CheckVisibility(node))
		return nullptr;

	/* relative to the node */
	rx -= node->box.pos[0];
	ry -= node->box.pos[1];

	/* check bounding box */
	if (rx < 0 || ry < 0 || rx >= node->box.size[0] || ry >= node->box.size[1])
		return nullptr;

	/** @todo we should improve the loop (last-to-first) */
	find = nullptr;
	if (node->firstChild) {
		uiNode_t *child;
		vec2_t clientPosition = {0, 0};

		if (UI_Node_IsScrollableContainer(node))
			UI_Node_GetClientPosition(node, clientPosition);

		rx -= clientPosition[0];
		ry -= clientPosition[1];

		for (child = node->firstChild; child; child = child->next) {
			uiNode_t *tmp;
			tmp = UI_GetNodeInTreeAtPosition(child, rx, ry);
			if (tmp)
				find = tmp;
		}

		rx += clientPosition[0];
		ry += clientPosition[1];
	}
	if (find)
		return find;

	/* disable ghost/excluderect in debug mode 2 */
	if (UI_DebugMode() != 2) {
		uiExcludeRect_t *excludeRect;
		/* is the node tangible */
		if (node->ghost)
			return nullptr;

		/* check excluded box */
		for (excludeRect = node->firstExcludeRect; excludeRect != nullptr; excludeRect = excludeRect->next) {
			if (rx >= excludeRect->pos[0]
			 && rx < excludeRect->pos[0] + excludeRect->size[0]
			 && ry >= excludeRect->pos[1]
			 && ry < excludeRect->pos[1] + excludeRect->size[1])
				return nullptr;
		}
	}

	/* we are over the node */
	return node;
}
Beispiel #3
0
/**
 * @sa UI_FocusExecuteActionNode
 * @note node must be in a window
 */
static uiNode_t* UI_GetNextActionNode (uiNode_t* node)
{
	if (node)
		node = node->next;
	while (node) {
		if (UI_CheckVisibility(node) && !node->invis
		 && ((node->onClick && node->onMouseEnter) || node->onMouseEnter))
			return node;
		node = node->next;
	}
	return nullptr;
}
Beispiel #4
0
/**
 * @brief Call mouse move only if the mouse position change
 */
bool UI_CheckMouseMove (void)
{
	/* is hovered node no more draw */
	if (hoveredNode && (hoveredNode->invis || !UI_CheckVisibility(hoveredNode)))
		UI_InvalidateMouse();

	if (mousePosX != oldMousePosX || mousePosY != oldMousePosY) {
		oldMousePosX = mousePosX;
		oldMousePosY = mousePosY;
		UI_MouseMove(mousePosX, mousePosY);
		return true;
	}

	return false;
}
Beispiel #5
0
/**
 * @todo need to merge UI model case, and the common case (looks to be a copy-pasted code)
 */
void UI_DrawModelNode (uiNode_t* node, const char* source)
{
	modelInfo_t mi;
	uiModel_t* model;
	vec3_t nodeorigin;
	vec2_t screenPos;

	assert(UI_NodeInstanceOf(node, "model"));			/**< We use model extradata */

	if (!source || source[0] == '\0')
		return;

	model = UI_GetUIModel(source);
	/* direct model name - no UI model definition */
	if (!model) {
		/* prevent the searching for a model def in the next frame */
		mi.model = R_FindModel(source);
		mi.name = source;
		if (!mi.model) {
			Com_Printf("Could not find model '%s'\n", source);
			return;
		}
	}

	/* compute the absolute origin ('origin' property is relative to the node center) */
	UI_GetNodeScreenPos(node, screenPos);
	UI_GetNodeAbsPos(node, nodeorigin);
	R_CleanupDepthBuffer(nodeorigin[0], nodeorigin[1], node->box.size[0], node->box.size[1]);
	if (EXTRADATA(node).clipOverflow) {
		UI_PushClipRect(screenPos[0], screenPos[1], node->box.size[0], node->box.size[1]);
	}
	nodeorigin[0] += node->box.size[0] / 2 + EXTRADATA(node).origin[0];
	nodeorigin[1] += node->box.size[1] / 2 + EXTRADATA(node).origin[1];
	nodeorigin[2] = EXTRADATA(node).origin[2];

	VectorMA(EXTRADATA(node).angles, cls.frametime, EXTRADATA(node).omega, EXTRADATA(node).angles);
	mi.origin = nodeorigin;
	mi.angles = EXTRADATA(node).angles;
	mi.scale = EXTRADATA(node).scale;
	mi.center = nullVector;
	mi.color = node->color;
	mi.mesh = 0;

	/* special case to draw models with UI model */
	if (model) {
		UI_DrawModelNodeWithUIModel(node, source, &mi, model);
		if (EXTRADATA(node).clipOverflow)
			UI_PopClipRect();
		return;
	}

	/* if the node is linked to a parent, the parent will display it */
	if (EXTRADATA(node).tag) {
		if (EXTRADATA(node).clipOverflow)
			UI_PopClipRect();
		return;
	}

	/* autoscale? */
	if (EXTRADATA(node).autoscale) {
		vec3_t autoScale;
		vec3_t autoCenter;
		const vec2_t size = {node->box.size[0] - node->padding, node->box.size[1] - node->padding};
		R_ModelAutoScale(size, &mi, autoScale, autoCenter);
	}

	/* no animation */
	mi.frame = 0;
	mi.oldframe = 0;
	mi.backlerp = 0;

	/* get skin */
	if (EXTRADATA(node).skin && *EXTRADATA(node).skin)
		mi.skin = atoi(UI_GetReferenceString(node, EXTRADATA(node).skin));
	else
		mi.skin = 0;

	/* do animations */
	if (EXTRADATA(node).animation && *EXTRADATA(node).animation) {
		const char* ref;
		ref = UI_GetReferenceString(node, EXTRADATA(node).animation);

		/* check whether the cvar value changed */
		if (strncmp(EXTRADATA(node).oldRefValue, source, MAX_OLDREFVALUE)) {
			Q_strncpyz(EXTRADATA(node).oldRefValue, source, MAX_OLDREFVALUE);
			/* model has changed but mem is already reserved in pool */
			Mem_Free(EXTRADATA(node).animationState);
			EXTRADATA(node).animationState = nullptr;
		}
		animState_t* as = EXTRADATA(node).animationState;
		if (!as) {
			as = Mem_PoolAllocType(animState_t, cl_genericPool);
			if (!as)
				Com_Error(ERR_DROP, "Model %s should have animState_t for animation %s - but doesn't\n", mi.name, ref);
			R_AnimChange(as, mi.model, ref);
			EXTRADATA(node).animationState = as;
		} else {
			const char* anim;
			/* change anim if needed */
			anim = R_AnimGetName(as, mi.model);
			if (anim && !Q_streq(anim, ref))
				R_AnimChange(as, mi.model, ref);
			R_AnimRun(as, mi.model, cls.frametime * 1000);
		}

		mi.frame = as->frame;
		mi.oldframe = as->oldframe;
		mi.backlerp = as->backlerp;
	}

	/* draw the main model on the node */
	R_DrawModelDirect(&mi, nullptr, nullptr);

	/* draw all children */
	if (node->firstChild) {
		uiNode_t* child;
		modelInfo_t pmi = mi;
		for (child = node->firstChild; child; child = child->next) {
			const char* tag;
			char childSource[MAX_VAR];
			const char* childRef;

			/* skip non "model" nodes */
			if (child->behaviour != node->behaviour)
				continue;

			/* skip invisible child */
			if (child->invis || !UI_CheckVisibility(child))
				continue;

			OBJZERO(mi);
			mi.angles = EXTRADATA(child).angles;
			mi.scale = EXTRADATA(child).scale;
			mi.center = nullVector;
			mi.origin = EXTRADATA(child).origin;
			mi.color = pmi.color;

			/* get the anchor name to link the model into the parent */
			tag = EXTRADATA(child).tag;

			/* init model name */
			childRef = UI_GetReferenceString(child, EXTRADATA(child).model);
			if (Q_strnull(childRef))
				childSource[0] = '\0';
			else
				Q_strncpyz(childSource, childRef, sizeof(childSource));
			mi.model = R_FindModel(childSource);
			mi.name = childSource;

			/* init skin */
			if (EXTRADATA(child).skin && *EXTRADATA(child).skin)
				mi.skin = atoi(UI_GetReferenceString(child, EXTRADATA(child).skin));
			else
				mi.skin = 0;

			R_DrawModelDirect(&mi, &pmi, tag);
		}
	}

	if (EXTRADATA(node).clipOverflow)
		UI_PopClipRect();
}