Exemplo n.º 1
0
void UI_CloseWindow (const char* name)
{
	uiNode_t *window = UI_GetWindow(name);
	if (window == NULL) {
		Com_Printf("Window '%s' not found\n", name);
		return;
	}

	/* found the correct add it to stack or bring it on top */
	UI_CloseWindowByRef(window);
}
Exemplo n.º 2
0
static void UI_DebugTree_f (void)
{
	const char *window;
	const uiNode_t *node;

	if (Cmd_Argc() != 2) {
		Com_Printf("Usage: %s <mainwindow>\n", Cmd_Argv(0));
		return;
	}

	window = Cmd_Argv(1);
	node = UI_GetWindow(window);
	UI_DebugTree(node, 0);
}
Exemplo n.º 3
0
/**
 * @brief Generates a popup that contains up to 3 buttons.
 * @param[in] title Title of the popup.
 * @param[in] text Text to display in the popup (use popupText if text is NULL).
 * @param[in] clickAction1 Action to perform when one clicked on the first button.
 * @param[in] clickText1 String that will be written in first button.
 * @param[in] tooltip1 Tooltip of first button.
 * @param[in] clickAction2 Action to perform when one clicked on the second button.
 * @param[in] clickText2 String that will be written in second button.
 * @param[in] tooltip2 Tooltip of second button.
 * @param[in] clickAction3 Action to perform when one clicked on the third button.
 * @param[in] clickText3 String that will be written in third button.
 * @param[in] tooltip3 Tooltip of third button.
 * @note clickAction AND clickText must be NULL if button should be invisible.
 */
void UI_PopupButton (const char *title, const char *text,
	const char *clickAction1, const char *clickText1, const char *tooltip1,
	const char *clickAction2, const char *clickText2, const char *tooltip2,
	const char *clickAction3, const char *clickText3, const char *tooltip3)
{
	uiNode_t* window;

	Cvar_Set("ui_sys_popup_title", title);
	if (text)
		UI_RegisterText(TEXT_POPUP_INFO, text);
	else
		UI_RegisterText(TEXT_POPUP_INFO, popupText);

	window = UI_GetWindow(POPUPBUTTON_WINDOW_NAME);
	if (!window)
		Com_Error(ERR_FATAL, "Could not get \""POPUPBUTTON_WINDOW_NAME"\" window");

	Cvar_Set("ui_sys_popup_button_text1", clickText1);
	Cvar_Set("ui_sys_popup_button_tooltip1", tooltip1);
	if (!clickAction1 && !clickText1) {
		UI_SetOneButton(window, va("%s1", POPUPBUTTON_NODE_NAME),
			NULL);
	} else {
		UI_SetOneButton(window, va("%s1", POPUPBUTTON_NODE_NAME),
			clickAction1 ? clickAction1 : popupAction1);
	}

	Cvar_Set("ui_sys_popup_button_text2", clickText2);
	Cvar_Set("ui_sys_popup_button_tooltip2", tooltip2);
	if (!clickAction2 && !clickText2) {
		UI_SetOneButton(window, va("%s2", POPUPBUTTON_NODE_NAME), NULL);
	} else {
		UI_SetOneButton(window, va("%s2", POPUPBUTTON_NODE_NAME),
			clickAction2 ? clickAction2 : popupAction2);
	}

	Cvar_Set("ui_sys_popup_button_text3", clickText3);
	Cvar_Set("ui_sys_popup_button_tooltip3", tooltip3);
	if (!clickAction3 && !clickText3) {
		UI_SetOneButton(window, va("%s3", POPUPBUTTON_NODE_NAME), NULL);
	} else {
		UI_SetOneButton(window, va("%s3", POPUPBUTTON_NODE_NAME),
			clickAction3 ? clickAction3 : popupAction3);
	}

	if (!UI_IsWindowOnStack(window->name))
		UI_PushWindow(window->name, NULL, NULL);
}
Exemplo n.º 4
0
/**
 * @note not moved into V_UI_NODEMETHOD because it is more a generic
 * tool than a method of the node editor
 */
static void UI_EditorNodeExtract_f (void)
{
	if (Cmd_Argc() != 2) {
		Com_Printf("Usage: %s <windowname>\n", Cmd_Argv(0));
		return;
	}
	uiNode_t* window = UI_GetWindow(Cmd_Argv(1));
	if (!window) {
		Com_Printf("Window '%s' not found\n", Cmd_Argv(1));
		return;
	}

	ScopedFile file;
	FS_OpenFile(va("window_%s_extracted.ufo", window->name), &file, FILE_WRITE);
	UI_EditorNodeExtractNode(&file, window, 0);

	Com_Printf("Window '%s' extracted.\n", Cmd_Argv(1));
}
Exemplo n.º 5
0
/**
 * @brief after execution of a unittest window, it analyse color of
 * normalized indicator, and create asserts. Both Fail/Pass asserts is
 * useful to count number.
 */
static void UFO_AnalyseTestWindow (const char* windowName)
{
	const uiBehaviour_t* stringBehaviour = UI_GetNodeBehaviour("string");
	const uiNode_t* node;
	const uiNode_t* window = UI_GetWindow(windowName);
	CU_ASSERT_FATAL(window != nullptr);
	CU_ASSERT_FATAL(stringBehaviour != nullptr);

	for (node = window->firstChild; node != nullptr; node = node->next) {
		bool isGreen;
		bool isRed;
		/* skip non "string" nodes */
		if (node->behaviour != stringBehaviour)
			continue;
		if (node->invis)
			continue;
		/* skip nodes without "test" prefix */
		if (!Q_strstart(node->name, "test"))
			continue;

		isGreen = node->color[0] < 0.1 && node->color[1] > 0.9 && node->color[2] < 0.1;
		isRed = node->color[0] > 0.9 && node->color[1] < 0.1 && node->color[2] < 0.1;

		if (isGreen) {
			/** @note Useful to count number of tests */
			CU_ASSERT_TRUE(true);
		} else if (isRed) {
			const char* message = va("%s.%s failed.", windowName, node->name);
			/*Com_Printf("Error: %s\n", message);*/
			/*CU_FAIL(message);*/
			CU_assertImplementation(CU_FALSE, 0, va("CU_FAIL(%s)", message), va("base/ufos/uitest/%s.ufo", windowName), "", CU_FALSE);
		} else {
			const char* message = va("%s.%s have an unknown status.", windowName, node->name);
			/*Com_Printf("Warning: %s\n", message);*/
			/*CU_FAIL(message);*/
			CU_assertImplementation(CU_FALSE, 0, va("CU_FAIL(%s)", message), va("base/ufos/uitest/%s.ufo", windowName), "", CU_FALSE);
		}
	}
}
Exemplo n.º 6
0
/**
 * @brief Generates a popup that contains a list of selectable choices.
 * @param[in] title Title of the popup.
 * @param[in] headline First line of text written in the popup.
 * @param[in] entries List of the selectables choices.
 * @param[in] clickAction Action to perform when one clicked on the popup.
 */
uiNode_t *UI_PopupList (const char *title, const char *headline, linkedList_t* entries, const char *clickAction)
{
	uiNode_t* window;
	uiNode_t* listNode;

	Cvar_Set("ui_sys_popup_title", title);
	UI_RegisterText(TEXT_POPUP_INFO, headline);

	/* make sure, that we are using the linked list */
	UI_ResetData(TEXT_LIST);
	UI_RegisterLinkedListText(TEXT_LIST, entries);

	window = UI_GetWindow(POPUPLIST_WINDOW_NAME);
	if (!window)
		Com_Error(ERR_FATAL, "Could not get "POPUPLIST_WINDOW_NAME" window");
	listNode = UI_GetNode(window, POPUPLIST_NODE_NAME);
	if (!listNode)
		Com_Error(ERR_FATAL, "Could not get "POPUPLIST_NODE_NAME" node in "POPUPLIST_WINDOW_NAME" window");

	/* free previous actions */
	if (listNode->onClick) {
		assert(listNode->onClick->d.terminal.d1.data);
		Mem_Free(listNode->onClick->d.terminal.d1.data);
		Mem_Free(listNode->onClick);
		listNode->onClick = NULL;
	}

	if (clickAction) {
		UI_PoolAllocAction(&listNode->onClick, EA_CMD, clickAction);
	} else {
		listNode->onClick = NULL;
	}

	if (!UI_IsWindowOnStack(window->name))
		UI_PushWindow(window->name, NULL, NULL);
	return listNode;
}
Exemplo n.º 7
0
/**
 * @brief Push a window onto the window stack
 * @param[in] name Name of the window to push onto window stack
 * @param[in] parentName Window name to link as parent-child (else NULL)
 * @param[in] params List of string parameters to send to the onWindowOpened method.
 * It can be NULL when there is no parameters, else this object must be freed by the caller.
 * @return A pointer to @c uiNode_t
 */
uiNode_t* UI_PushWindow (const char *name, const char *parentName, linkedList_t *params)
{
	uiNode_t *window;

	UI_ReleaseInput();

	window = UI_GetWindow(name);
	if (window == NULL) {
		Com_Printf("Window \"%s\" not found.\n", name);
		return NULL;
	}

	UI_DeleteWindowFromStack(window);

	if (ui_global.windowStackPos < UI_MAX_WINDOWSTACK)
		if (parentName) {
			const int parentPos = UI_GetWindowPositionFromStackByName(parentName);
			if (parentPos == -1) {
				Com_Printf("Didn't find parent window \"%s\" for window push of \"%s\"\n", parentName, name);
				return NULL;
			}
			UI_InsertWindowIntoStack(window, parentPos + 1);
			WINDOWEXTRADATA(window).parent = ui_global.windowStack[parentPos];
		} else
			ui_global.windowStack[ui_global.windowStackPos++] = window;
	else
		Com_Printf("Window stack overflow\n");

	UI_Node_WindowOpened(window, params);

	/* change from e.g. console mode to game input mode (fetch input) */
	Key_SetDest(key_game);

	UI_InvalidateMouse();
	return window;
}
Exemplo n.º 8
0
/**
 * @brief Parse a window
 * @sa CL_ParseClientData
 * @code
 * window windowName {
 * }
 * @endcode
 */
bool UI_ParseWindow (const char* type, const char* name, const char** text)
{
	const char* errhead = "UI_ParseWindow: unexpected end of file (window";
	uiNode_t* window;
	const char* token;
	int i;

	if (!Q_streq(type, "window")) {
		Com_Error(ERR_FATAL, "UI_ParseWindow: '%s %s' is not a window node\n", type, name);
		return false;	/* never reached */
	}

	if (!UI_TokenIsName(name, Com_GetType(text) == TT_QUOTED_WORD)) {
		Com_Printf("UI_ParseWindow: \"%s\" is not a well formed node name ([a-zA-Z_][a-zA-Z0-9_]*)\n", name);
		return false;
	}
	if (UI_TokenIsReserved(name)) {
		Com_Printf("UI_ParseWindow: \"%s\" is a reserved token, we can't call a node with it (node \"%s\")\n", name, name);
		return false;
	}

	/* search for windows with same name */
	for (i = 0; i < ui_global.numWindows; i++)
		if (!strncmp(name, ui_global.windows[i]->name, sizeof(ui_global.windows[i]->name)))
			break;

	if (i < ui_global.numWindows) {
		Com_Printf("UI_ParseWindow: %s \"%s\" with same name found, second ignored\n", type, name);
	}

	if (ui_global.numWindows >= UI_MAX_WINDOWS) {
		Com_Error(ERR_FATAL, "UI_ParseWindow: max windows exceeded (%i) - ignore '%s'\n", UI_MAX_WINDOWS, name);
		return false;	/* never reached */
	}

	/* get window body */
	token = Com_Parse(text);

	/* does this window inherit data from another window? */
	if (Q_streq(token, "extends")) {
		uiNode_t* superWindow;
		token = Com_Parse(text);
		superWindow = UI_GetWindow(token);
		if (superWindow == nullptr)
			Sys_Error("Could not get the super window \"%s\"", token);
		window = UI_CloneNode(superWindow, nullptr, true, name, false);
		token = Com_Parse(text);
	} else {
		window = UI_AllocNode(name, type, false);
		window->root = window;
	}

	UI_InsertWindow(window);

	/* parse it's body */
	bool result = UI_ParseNodeBody(window, text, &token, errhead);
	if (!result) {
		Com_Error(ERR_FATAL, "UI_ParseWindow: window \"%s\" has a bad body\n", window->name);
	}

	UI_Node_Loaded(window);
	return true;
}
Exemplo n.º 9
0
/**
 * @brief Read a path and return every we can use (node and property)
 * @details The path token must be a window name, and then node child.
 * Reserved token 'root' and 'parent' can be used to navigate.
 * If relativeNode is set, the path can start with reserved token
 * 'this', 'root' and 'parent' (relative to this node).
 * The function can return a node property by using a '\@',
 * the path 'foo\@pos' will return the window foo and the property 'pos'
 * from the 'window' behaviour.
 * @param[in] path Path to read. Contain a node location with dot seprator and a facultative property
 * @param[in] relativeNode relative node where the path start. It allow to use facultative command to start the path (this, parent, root).
 * @param[out] resultNode Node found. Else NULL.
 * @param[out] resultProperty Property found. Else NULL.
 * TODO Speed up, evilly used function, use strncmp instead of using buffer copy (name[MAX_VAR])
 */
void UI_ReadNodePath (const char* path, const uiNode_t *relativeNode, uiNode_t **resultNode, const value_t **resultProperty)
{
	char name[MAX_VAR];
	uiNode_t* node = NULL;
	const char* nextName;
	char nextCommand = '^';

	*resultNode = NULL;
	if (resultProperty)
		*resultProperty = NULL;

	nextName = path;
	while (nextName && nextName[0] != '\0') {
		const char* begin = nextName;
		char command = nextCommand;
		nextName = strpbrk(begin, ".@#");
		if (!nextName) {
			Q_strncpyz(name, begin, sizeof(name));
			nextCommand = '\0';
		} else {
			assert(nextName - begin + 1 <= sizeof(name));
			Q_strncpyz(name, begin, nextName - begin + 1);
			nextCommand = *nextName;
			nextName++;
		}

		switch (command) {
		case '^':	/* first string */
			if (Q_streq(name, "this")) {
				if (relativeNode == NULL)
					return;
				/** @todo find a way to fix the bad cast. only here to remove "discards qualifiers" warning */
				node = *(uiNode_t**) ((void*)&relativeNode);
			} else if (Q_streq(name, "parent")) {
				if (relativeNode == NULL)
					return;
				node = relativeNode->parent;
			} else if (Q_streq(name, "root")) {
				if (relativeNode == NULL)
					return;
				node = relativeNode->root;
			} else
				node = UI_GetWindow(name);
			break;
		case '.':	/* child node */
			if (Q_streq(name, "parent"))
				node = node->parent;
			else if (Q_streq(name, "root"))
				node = node->root;
			else
				node = UI_GetNode(node, name);
			break;
		case '#':	/* window index */
			/** @todo FIXME use a warning instead of an assert */
			assert(node->behaviour == ui_windowBehaviour);
			node = UI_WindowNodeGetIndexedChild(node, name);
			break;
		case '@':	/* property */
			assert(nextCommand == '\0');
			*resultProperty = UI_GetPropertyFromBehaviour(node->behaviour, name);
			*resultNode = node;
			return;
		}

		if (!node)
			return;
	}

	*resultNode = node;
	return;
}
Exemplo n.º 10
0
/**
 * @brief Read a path and return every we can use (node and property)
 * @details The path token must be a window name, and then node child.
 * Reserved token 'root' and 'parent' can be used to navigate.
 * If relativeNode is set, the path can start with reserved token
 * 'this', 'root', 'parent' and 'child' (relative to this node).
 * The function can return a node property by using a '\@',
 * the path 'foo\@pos' will return the window foo and the property 'pos'
 * from the 'window' behaviour.
 * @param[in] path Path to read. Contain a node location with dot seprator and a facultative property
 * @param[in] relativeNode relative node where the path start. It allow to use facultative command to start the path (this, parent, root).
 * @param[in] iterationNode relative node referencing child in 'forchildin' iteration, mapped to '*node:child', can be nullptr
 * @param[out] resultNode Node found. Else nullptr.
 * @param[out] resultProperty Property found. Else nullptr.
 * @param[in,out] luaMethod A pointer to a value_t structure that is filled with a lua based method identification, can be nullptr
 * @note If luaMethod is set, the method will scan the known lua methods defined on the behaviour. If luaMethod is not set, only
 * registered local properties are scanned.
 * @todo Speed up, evilly used function, use strncmp instead of using buffer copy (name[MAX_VAR])
 * @note If luaMethod is set, make sure to release the allocated .name string.
 */
void UI_ReadNodePath (const char* path, const uiNode_t* relativeNode, const uiNode_t* iterationNode, uiNode_t** resultNode, const value_t** resultProperty, value_t *luaMethod) {
	char name[MAX_VAR];
	uiNode_t* node = nullptr;
	uiNode_t* childnode = nullptr;
	const char* nextName;
	char nextCommand = '^';

	*resultNode = nullptr;
	if (resultProperty)
		*resultProperty = nullptr;

	nextName = path;
	while (nextName && nextName[0] != '\0') {
		const char* begin = nextName;
		char command = nextCommand;
		nextName = strpbrk(begin, ".@#");
		if (!nextName) {
			Q_strncpyz(name, begin, sizeof(name));
			nextCommand = '\0';
		} else {
			assert(nextName - begin + 1 <= sizeof(name));
			Q_strncpyz(name, begin, nextName - begin + 1);
			nextCommand = *nextName;
			nextName++;
		}

		switch (command) {
		case '^':	/* first string */
			if (Q_streq(name, "this")) {
				if (relativeNode == nullptr)
					return;
				node = const_cast<uiNode_t *>(relativeNode);
			} else if (Q_streq(name, "parent")) {
				if (relativeNode == nullptr)
					return;
				node = relativeNode->parent;
			} else if (Q_streq(name, "root")) {
				if (relativeNode == nullptr)
					return;
				node = relativeNode->root;
			} else if (Q_streq(name, "child")) {
				if (iterationNode == nullptr)
					return;
				node = const_cast<uiNode_t *>(iterationNode);
			} else
				node = UI_GetWindow(name);
			break;
		case '.':	/* child node */
			if (Q_streq(name, "parent"))
				childnode = node->parent;
			else if (Q_streq(name, "root"))
				childnode = node->root;
			else {
				childnode = UI_GetNode(node, name);
				/* if no node found and if we need it, then it is possible we call a lua based function */
				if (luaMethod && !childnode) {
					*resultProperty = UI_GetPropertyOrLuaMethod(node, name, luaMethod);
					if (luaMethod->type) {
						childnode = node;
					}
				}
			}
			node = childnode;
			break;
		case '#':	/* window index */
			/** @todo FIXME use a warning instead of an assert */
			assert(UI_Node_IsWindow(node));
			node = UI_WindowNodeGetIndexedChild(node, name);
			break;
		case '@':	/* property */
			assert(nextCommand == '\0');
			*resultProperty = UI_GetPropertyOrLuaMethod(node, name, luaMethod);
			*resultNode = node;
			return;
		}

		if (!node)
			return;
	}

	*resultNode = node;
	return;
}