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 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 #2
0
/**
 * @brief Update an absolute position to a relative one
 * @param[in] node Context node
 * @param[in,out] x an absolute x position
 * @param[in,out] y an absolute y position
 */
void UI_NodeAbsoluteToRelativePos (const uiNode_t* node, int* x, int* y)
{
	assert(node != nullptr);
	/* if we request the position of an undrawable node, there is a problem */
	assert(node->behaviour->isVirtual == false);
	assert(x != nullptr);
	assert(y != nullptr);

	/* if we request the position of an undrawable node, there is a problem */
	if (node->behaviour->isVirtual)
		Com_Error(ERR_DROP, "UI_NodeAbsoluteToRelativePos: Node '%s' doesn't have a position", node->name);

	while (node) {
		*x -= node->box.pos[0];
		*y -= node->box.pos[1];

		if (UI_Node_IsScrollableContainer(node)) {
			vec2_t clientPosition = {0, 0};
			UI_Node_GetClientPosition(node, clientPosition);
			*x -= clientPosition[0];
			*y -= clientPosition[1];
		}

		node = node->parent;
	}
}
Beispiel #3
0
/**
 * @brief Returns the absolute position of a node in the screen.
 * Screen position is not used for the node rendering cause we use OpenGL
 * translations. But this function is need for some R_functions methodes.
 * @param[in] node Context node
 * @param[out] pos Absolute position into the screen
 */
void UI_GetNodeScreenPos (const uiNode_t* node, vec2_t pos)
{
	assert(node);
	assert(pos);

	/* if we request the position of a non drawable node, there is a problem */
	if (node->behaviour->isVirtual)
		Com_Error(ERR_FATAL, "UI_GetNodeAbsPos: Node '%s' doesn't have a position", node->name);

	Vector2Set(pos, 0, 0);
	while (node) {
#ifdef DEBUG
		if (node->box.pos[0] != (int)node->box.pos[0] || node->box.pos[1] != (int)node->box.pos[1])
			Com_Error(ERR_FATAL, "UI_GetNodeAbsPos: Node '%s' position %f,%f is not integer", UI_GetPath(node), node->box.pos[0], node->box.pos[1]);
#endif
		pos[0] += node->box.pos[0];
		pos[1] += node->box.pos[1];
		node = node->parent;

		if (node && UI_Node_IsScrollableContainer(node)) {
			vec2_t clientPosition = {0, 0};
			UI_Node_GetClientPosition(node, clientPosition);
			pos[0] += clientPosition[0];
			pos[1] += clientPosition[1];
		}
	}
}
/**
 * @brief return true if the node size change and update the cache
 */
bool uiAbstractScrollableNode::isSizeChange (uiNode_t *node)
{
	assert(UI_Node_IsScrollableContainer(node));

	if (!Vector2Equal(node->box.size, EXTRADATA(node).cacheSize)) {
		Vector2Copy(node->box.size, EXTRADATA(node).cacheSize);
		return true;
	}
	return false;
}
/**
 * @brief Set the Y scroll to a position, and call event if need
 * @param[in] node Context node
 * @param[in] viewPos New position to set, else -1 if no change
 * @param[in] viewSize New view size to set, else -1 if no change
 * @param[in] fullSize New full size to set, else -1 if no change
 * @return True, if something have change
 */
bool uiAbstractScrollableNode::setScrollY (uiNode_t *node, int viewPos, int viewSize, int fullSize)
{
	bool updated;
	assert(UI_Node_IsScrollableContainer(node));

	updated = EXTRADATA(node).scrollY.set(viewPos, viewSize, fullSize);

	if (updated && EXTRADATA(node).onViewChange)
		UI_ExecuteEventActions(node, EXTRADATA(node).onViewChange);

	return updated;
}
/**
 * @brief Scroll the Y scroll with a relative position, and call event if need
 * @return true, if something have change
 */
bool uiAbstractScrollableNode::scrollY (uiNode_t *node, int offset)
{
	assert(UI_Node_IsScrollableContainer(node));
	return setScrollY(node, EXTRADATA(node).scrollY.viewPos + offset, -1, -1);
}