Example #1
0
/**
 * @brief Callback to execute a confunc
 */
static void UI_ConfuncCommand_f (void)
{
	uiNode_t *node = (uiNode_t *) Cmd_Userdata();
	assert(node);
	assert(UI_NodeInstanceOf(node, "confunc"));
	UI_ExecuteConFuncActions(node, node->onClick);
}
Example #2
0
/**
 * @brief Get the line number under an absolute position
 * @param[in] node a text node
 * @param[in] x,y position on the screen
 * @return The line number under the position (0 = first line)
 */
static int UI_TextNodeGetLine (const uiNode_t* node, int x, int y)
{
	int lineHeight;
	int line;
	assert(UI_NodeInstanceOf(node, "text"));

	lineHeight = EXTRADATACONST(node).lineHeight;
	if (lineHeight == 0) {
		const char* font = UI_GetFontFromNode(node);
		lineHeight = UI_FontGetHeight(font);
	}

	UI_NodeAbsoluteToRelativePos(node, &x, &y);
	y -= node->padding;

	/* skip position over the first line */
	if (y < 0)
		 return -1;
	line = (int) (y / lineHeight) + EXTRADATACONST(node).super.scrollY.viewPos;

	/* skip position under the last line */
	if (line >= EXTRADATACONST(node).super.scrollY.fullSize)
		return -1;

	return line;
}
Example #3
0
/**
 * @brief Checks whether the given node is a virtual confunc that can be overridden from inheriting nodes.
 * @param node The node to check (must be a confunc node).
 * @return @c true if the given node is a dummy node, @c false otherwise.
 */
static qboolean UI_ConFuncIsVirtual (const uiNode_t *const node)
{
	/* magic way to know if it is a dummy node (used for inherited confunc) */
	const uiNode_t *dummy = (const uiNode_t*) Cmd_GetUserdata(node->name);
	assert(node);
	assert(UI_NodeInstanceOf(node, "confunc"));
	return (dummy != NULL && dummy->parent == NULL);
}
Example #4
0
/**
 * @brief Checks whether the given node is a virtual confunc that can be overridden from inheriting nodes.
 * @param node The node to check (must be a confunc node).
 * @return @c true if the given node is a dummy node, @c false otherwise.
 */
static bool UI_ConFuncIsVirtual (const uiNode_t* const node)
{
    /* magic way to know if it is a dummy node (used for inherited confunc) */
    const uiNode_t* dummy = static_cast<const uiNode_t*>(Cmd_GetUserdata(node->name));
    assert(node);
    assert(UI_NodeInstanceOf(node, "confunc"));
    return (dummy != nullptr && dummy->parent == nullptr);
}
/**
 * @brief return true if the node size change and update the cache
 */
qboolean UI_AbstractScrollableNodeIsSizeChange (uiNode_t *node)
{
	assert(UI_NodeInstanceOf(node, "abstractscrollable"));

	if (!Vector2Equal(node->size, EXTRADATA(node).cacheSize)) {
		Vector2Copy(node->size, EXTRADATA(node).cacheSize);
		return qtrue;
	}
	return qfalse;
}
Example #6
0
/**
 * @brief Search a a key binding from a window node.
 * Window node store key bindings for his node child.
 * @param node A window node
 * @param key A key code, either K_ value or lowercase ascii
 */
uiKeyBinding_t* UI_WindowNodeGetKeyBinding (uiNode_t const* const node, unsigned int key)
{
	uiKeyBinding_t* binding = EXTRADATACONST(node).keyList;
	assert(UI_NodeInstanceOf(node, "window"));
	while (binding) {
		if (binding->key == key)
			break;
		binding = binding->next;
	}
	return binding;
}
/**
 * @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
 */
qboolean UI_AbstractScrollableNodeSetY (uiNode_t *node, int viewPos, int viewSize, int fullSize)
{
	qboolean updated;
	assert(UI_NodeInstanceOf(node, "abstractscrollable"));

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

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

	return updated;
}
Example #8
0
/**
 * @brief Callback to execute a confunc
 */
static void UI_ConfuncCommand_f (void)
{
    uiNode_t* node = static_cast<uiNode_t*>(Cmd_Userdata());
    assert(node);
    assert(UI_NodeInstanceOf(node, "confunc"));
    if (node->onClick != nullptr) {
        UI_ExecuteConFuncActions(node, node->onClick);
    }
    if (node->lua_onClick != LUA_NOREF) {
        UI_ExecuteLuaConFunc (node, node->lua_onClick);
    }
}
Example #9
0
/**
 * @brief Scroll to the bottom
 * @param[in] nodePath absolute path
 */
void UI_TextScrollEnd (const char* nodePath)
{
	uiNode_t* node = UI_GetNodeByPath(nodePath);
	if (!node) {
		Com_DPrintf(DEBUG_CLIENT, "UI_TextScrollEnd: Node '%s' could not be found\n", nodePath);
		return;
	}

	if (!UI_NodeInstanceOf(node, "text")) {
		Com_Printf("UI_TextScrollEnd: '%s' node is no instance of 'text'.\n", Cmd_Argv(1));
		return;
	}

	uiTextNode* b = dynamic_cast<uiTextNode*>(node->behaviour->manager.get());
	b->validateCache(node);

	if (EXTRADATA(node).super.scrollY.fullSize > EXTRADATA(node).super.scrollY.viewSize) {
		EXTRADATA(node).super.scrollY.viewPos = EXTRADATA(node).super.scrollY.fullSize - EXTRADATA(node).super.scrollY.viewSize;
		UI_ExecuteEventActions(node, EXTRADATA(node).super.onViewChange);
	}
}
Example #10
0
/**
 * @brief Active an element of a vscrollbarnode.
 * @note This command work like an user, so, if need, change event are fired
 */
static void UI_ActiveVScrollbarNode_f ()
{
	uiNode_t *node;
	int actionId;

	if (Cmd_Argc() != 3) {
		Com_Printf("Usage: %s <node-path> <action-id>\n", Cmd_Argv(0));
		return;
	}

	node = UI_GetNodeByPath(Cmd_Argv(1));
	if (node == NULL) {
		Com_Printf("UI_ActiveVScrollbarNode_f: node '%s' not found\n", Cmd_Argv(1));
		return;
	}
	if (!UI_NodeInstanceOf(node, "vscrollbar")) {
		Com_Printf("UI_ActiveVScrollbarNode_f: node '%s' is not a 'vscrollbar'\n", Cmd_Argv(1));
		return;
	}

	actionId = atoi(Cmd_Argv(2));
	UI_VScrollbarNodeAction(node, actionId, qfalse);
}
Example #11
0
/**
 * @brief Add a key binding to a window node.
 * Window node store key bindings for his node child.
 * @param node A window node
 * @param binding Key binding to link with the window (structure should not be already linked somewhere)
 * @todo Rework that function to remove possible wrong use of that function
 */
void UI_WindowNodeRegisterKeyBinding (uiNode_t* node, uiKeyBinding_t* binding)
{
	assert(UI_NodeInstanceOf(node, "window"));
	binding->next = EXTRADATA(node).keyList;
	EXTRADATA(node).keyList = binding;
}
Example #12
0
/**
 * @brief Check if a window is fullscreen or not
 */
bool UI_WindowIsFullScreen (const uiNode_t* const node)
{
	assert(UI_NodeInstanceOf(node, "window"));
	return EXTRADATACONST(node).isFullScreen;
}
/**
 * @brief Scroll the Y scroll with a relative position, and call event if need
 * @return True, if something have change
 */
qboolean UI_AbstractScrollableNodeScrollY (uiNode_t *node, int offset)
{
	assert(UI_NodeInstanceOf(node, "abstractscrollable"));
	return UI_AbstractScrollableNodeSetY(node, EXTRADATA(node).scrollY.viewPos + offset, -1, -1);
}
Example #14
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();
}