Beispiel #1
0
/**
 * @brief Remove the higher element (in alphabet) from a list
 * @todo option should start with '_' if we need to translate it
 * @warning update parent
 */
static uiNode_t* UI_OptionNodeRemoveHigherOption (uiNode_t** option)
{
	uiNode_t* prev = *option;
	uiNode_t* prevfind = nullptr;
	uiNode_t* search = (*option)->next;
	const char* label = CL_Translate(OPTIONEXTRADATA(*option).label);

	/* search the smaller element */
	while (search) {
		const char* searchlabel = CL_Translate(OPTIONEXTRADATA(search).label);
		if (strcmp(label, searchlabel) < 0) {
			prevfind = prev;
			label = searchlabel;
		}
		prev = search;
		search = search->next;
	}

	/* remove the first element */
	if (prevfind == nullptr) {
		uiNode_t* tmp = *option;
		*option = (*option)->next;
		return tmp;
	} else {
		uiNode_t* tmp = prevfind->next;
		prevfind->next = tmp->next;
		return tmp;
	}
}
Beispiel #2
0
/**
 * @sa Com_MacroExpandString
 * @todo we should review this code, '*' doesn't work very well for all the needed things
 */
const char *UI_GetReferenceString (const uiNode_t* const node, const char *ref)
{
	if (!ref)
		return nullptr;

	/* its a cvar */
	if (ref[0] != '*')
		return CL_Translate(ref);

	/* get the reference and the name */
	const char *token = Com_MacroExpandString(ref);
	if (token)
		return CL_Translate(token);

	/* skip the star */
	token = ref + 1;
	if (token[0] == '\0')
		return nullptr;

	if (char const* const binding = Q_strstart(token, "binding:")) {
		return Key_GetBinding(binding, cls.state != ca_active ? KEYSPACE_UI : KEYSPACE_GAME);
	}

	Sys_Error("UI_GetReferenceString: unknown reference %s", token);
}
Beispiel #3
0
/**
 * @brief Draw a text node
 */
void uiTextNode::draw (uiNode_t* node)
{
	const uiSharedData_t* shared;

	if (EXTRADATA(node).dataID == TEXT_NULL && node->text != nullptr) {
		const char* t = CL_Translate(UI_GetReferenceString(node, node->text));
		drawText(node, t, nullptr, false);
		return;
	}

	shared = &ui_global.sharedData[EXTRADATA(node).dataID];

	switch (shared->type) {
	case UI_SHARED_TEXT:
	{
		const char* t = CL_Translate(shared->data.text);
		drawText(node, t, nullptr, false);
		break;
	}
	case UI_SHARED_LINKEDLISTTEXT:
		drawText(node, nullptr, shared->data.linkedListText, false);
		break;
	default:
		break;
	}

	EXTRADATA(node).versionId = shared->versionId;
}
Beispiel #4
0
void uiTextNode::updateCache (uiNode_t* node)
{
	const uiSharedData_t* shared;

	if (EXTRADATA(node).dataID == TEXT_NULL && node->text != nullptr)
		return;

	shared = &ui_global.sharedData[EXTRADATA(node).dataID];

	switch (shared->type) {
	case UI_SHARED_TEXT:
		{
			const char* t = CL_Translate(shared->data.text);
			drawText(node, t, nullptr, true);
		}
		break;
	case UI_SHARED_LINKEDLISTTEXT:
		drawText(node, nullptr, shared->data.linkedListText, true);
		break;
	default:
		break;
	}

	EXTRADATA(node).versionId = shared->versionId;
}
Beispiel #5
0
void uiSelectBoxNode::draw (uiNode_t* node)
{
	uiNode_t* option;
	int selBoxX, selBoxY;
	const char* ref;
	const char* font;
	vec2_t nodepos;
	const char* imageName;
	const image_t* image;
	static vec4_t invisColor = {1.0, 1.0, 1.0, 0.7};

	ref = UI_AbstractOptionGetCurrentValue(node);
	if (ref == nullptr)
		return;

	UI_GetNodeAbsPos(node, nodepos);
	imageName = UI_GetReferenceString(node, node->image);
	if (!imageName)
		imageName = "ui/selectbox";

	image = UI_LoadImage(imageName);

	font = UI_GetFontFromNode(node);
	selBoxX = nodepos[0] + SELECTBOX_SIDE_WIDTH;
	selBoxY = nodepos[1] + SELECTBOX_SPACER;

	/* left border */
	UI_DrawNormImage(false, nodepos[0], nodepos[1], SELECTBOX_SIDE_WIDTH, node->box.size[1],
		SELECTBOX_SIDE_WIDTH, SELECTBOX_DEFAULT_HEIGHT, 0.0f, 0.0f, image);
	/* stretched middle bar */
	UI_DrawNormImage(false, nodepos[0] + SELECTBOX_SIDE_WIDTH, nodepos[1], node->box.size[0]-SELECTBOX_SIDE_WIDTH-SELECTBOX_RIGHT_WIDTH, node->box.size[1],
		12.0f, SELECTBOX_DEFAULT_HEIGHT, 7.0f, 0.0f, image);
	/* right border (arrow) */
	UI_DrawNormImage(false, nodepos[0] + node->box.size[0] - SELECTBOX_RIGHT_WIDTH, nodepos[1], SELECTBOX_DEFAULT_HEIGHT, node->box.size[1],
		12.0f + SELECTBOX_RIGHT_WIDTH, SELECTBOX_DEFAULT_HEIGHT, 12.0f, 0.0f, image);

	/* draw the label for the current selected option */
	for (option = UI_AbstractOptionGetFirstOption(node); option; option = option->next) {
		if (!Q_streq(OPTIONEXTRADATA(option).value, ref))
			continue;

		if (option->invis)
			R_Color(invisColor);

		const char* label = CL_Translate(OPTIONEXTRADATA(option).label);

		UI_DrawString(font, ALIGN_UL, selBoxX, selBoxY,
			selBoxX, node->box.size[0] - 4,
			0, label, 0, 0, nullptr, false, LONGLINES_PRETTYCHOP);

		R_Color(nullptr);
		break;
	}

	/* must we draw the drop-down list */
	if (UI_GetMouseCapture() == node) {
		UI_CaptureDrawOver(node);
	}
}
Beispiel #6
0
static inline void UI_ExecuteSetAction (const uiAction_t* action, const uiCallContext_t* context)
{
    const char* path;
    uiNode_t* node;
    const value_t* property;
    const uiAction_t* left;
    uiAction_t* right;

    left = action->d.nonTerminal.left;
    if (left == nullptr) {
        Com_Printf("UI_ExecuteSetAction: Action without left operand skipped.\n");
        return;
    }

    right = action->d.nonTerminal.right;
    if (right == nullptr) {
        Com_Printf("UI_ExecuteSetAction: Action without right operand skipped.\n");
        return;
    }

    if (left->type == EA_VALUE_CVARNAME || left->type == EA_VALUE_CVARNAME_WITHINJECTION) {
        const char* cvarName;

        if (left->type == EA_VALUE_CVARNAME)
            cvarName = left->d.terminal.d1.constString;
        else
            cvarName = UI_GenInjectedString(left->d.terminal.d1.constString, false, context);

        const char* textValue = CL_Translate(UI_GetStringFromExpression(right, context));
        Cvar_ForceSet(cvarName, textValue);
        return;
    }

    /* search the node */
    if (left->type == EA_VALUE_PATHPROPERTY)
        path = left->d.terminal.d1.constString;
    else if (left->type == EA_VALUE_PATHPROPERTY_WITHINJECTION)
        path = UI_GenInjectedString(left->d.terminal.d1.constString, false, context);
    else
        Com_Error(ERR_FATAL, "UI_ExecuteSetAction: Property setter with wrong type '%d'", left->type);

    /* context->tagNode holds reference to child in iteration loop if applicable */
    UI_ReadNodePath(path, context->source, context->tagNode, &node, &property);
    if (!node) {
        Com_Printf("UI_ExecuteSetAction: node \"%s\" doesn't exist (source: %s)\n", path, UI_GetPath(context->source));
        return;
    }
    if (!property) {
        Com_Printf("UI_ExecuteSetAction: property \"%s\" doesn't exist (source: %s)\n", path, UI_GetPath(context->source));
        return;
    }

    UI_NodeSetPropertyFromActionValue(node, property, context, right);
}
Beispiel #7
0
/**
 * @brief Return a tab located at a screen position
 * @param[in] node A tab node
 * @param[in] x The x position of the screen to test
 * @param[in] y The x position of the screen to test
 * @return A uiNode_t, or NULL if nothing.
 * @todo improve test when we are on a junction
 * @todo improve test when we are on a chopped tab
 */
static uiNode_t* UI_TabNodeTabAtPosition (const uiNode_t *node, int x, int y)
{
	const char *font;
	uiNode_t* option;
	uiNode_t* prev = NULL;
	int allowedWidth;

	UI_NodeAbsoluteToRelativePos(node, &x, &y);

	/** @todo this dont work when an option is hidden */
	allowedWidth = node->box.size[0] - TILE_WIDTH * (EXTRADATACONST(node).count + 1);

	/* Bounded box test (shound not need, but there are problem) */
	if (x < 0 || y < 0 || x >= node->box.size[0] || y >= node->box.size[1])
		return NULL;

	font = UI_GetFontFromNode(node);

	/* Text box test */
	for (option = node->firstChild; option; option = option->next) {
		int tabWidth;
		assert(option->behaviour == ui_optionBehaviour);

		/* skip hidden options */
		if (option->invis)
			continue;

		if (x < TILE_WIDTH / 2)
			return prev;

		const char *label = CL_Translate(OPTIONEXTRADATA(option).label);

		R_FontTextSize(font, label, 0, LONGLINES_PRETTYCHOP, &tabWidth, NULL, NULL, NULL);
		if (OPTIONEXTRADATA(option).icon && OPTIONEXTRADATA(option).icon->size[0] < allowedWidth) {
			tabWidth += OPTIONEXTRADATA(option).icon->size[0];
		}
		if (tabWidth > allowedWidth) {
			if (allowedWidth > 0)
				tabWidth = allowedWidth;
			else
				tabWidth = 0;
		}

		if (x < tabWidth + TILE_WIDTH)
			return option;

		allowedWidth -= tabWidth;
		x -= tabWidth + TILE_WIDTH;
		prev = option;
	}
	if (x < TILE_WIDTH / 2)
		return prev;
	return NULL;
}
Beispiel #8
0
/**
 * @sa Com_MacroExpandString
 * @todo we should review this code, '*' doesn't work very well for all the needed things
 */
const char* UI_GetReferenceString (const uiNode_t* const node, const char* ref)
{
	if (!ref)
		return nullptr;

	/* its a cvar */
	if (ref[0] != '*')
		return CL_Translate(ref);

	/* get the reference and the name */
	const char* token = Com_MacroExpandString(ref);
	if (token)
		return CL_Translate(token);

	/* skip the star */
	token = ref + 1;
	if (token[0] == '\0')
		return nullptr;

	Sys_Error("UI_GetReferenceString: unknown reference %s", token);
}
Beispiel #9
0
/**
 * @brief Custom tooltip of tab node
 * @param[in] node Node we request to draw tooltip
 * @param[in] x Position x of the mouse
 * @param[in] y Position y of the mouse
 */
void uiTabNode::drawTooltip (uiNode_t *node, int x, int y)
{
	uiNode_t *option;
	const int tooltipWidth = 250;

	option = UI_TabNodeTabAtPosition(node, x, y);
	if (option == NULL)
		return;

	if (!OPTIONEXTRADATA(option).truncated)
		return;

	const char *label = CL_Translate(OPTIONEXTRADATA(option).label);
	UI_DrawTooltip(label, x, y, tooltipWidth);
}
Beispiel #10
0
static void UI_TextNodeGenerateLineSplit (uiNode_t* node)
{
	const char* data;
	int bufferSize = 1024;
	char* buffer = Mem_AllocTypeN(char, bufferSize);

	LIST_Delete(&EXTRADATA(node).lineSplit);

	if (node->text != nullptr)
		data = UI_GetReferenceString(node, node->text);
	else if (EXTRADATA(node).super.dataID != TEXT_NULL) {
		const uiSharedData_t* shared;
		shared = &ui_global.sharedData[EXTRADATA(node).super.dataID];
		switch (shared->type) {
		case UI_SHARED_TEXT:
			data = UI_GetText(EXTRADATA(node).super.dataID);
			break;
		case UI_SHARED_LINKEDLISTTEXT:
			return;
		default:
			return;
		}
	} else
		return;

	data = CL_Translate(data);

	while (data[0] != '\0') {
		const char* next = strchr(data, '\n');
		int lineSize;
		if (next == nullptr)
			lineSize = strlen(data);
		else
			lineSize = next - data;

		if (lineSize + 1 > bufferSize) {
			bufferSize = lineSize + 1;
			Mem_Free(buffer);
			buffer = Mem_AllocTypeN(char, bufferSize);
		}

		Q_strncpyz(buffer, data, lineSize + 1);
		LIST_AddString(&EXTRADATA(node).lineSplit, buffer);

		if (next == nullptr)
			break;
		data = next + 1;
	}
void uiOptionListNode::draw (uiNode_t* node)
{
	uiNode_t* option;
	const char* ref;
	const char* font;
	int lineHeight;
	vec2_t pos;
	int currentY;
	const float* textColor;
	int count = 0;

	ref = UI_AbstractOptionGetCurrentValue(node);
	if (ref == nullptr)
		return;

	UI_GetNodeAbsPos(node, pos);

	if (EXTRADATA(node).background) {
		UI_DrawSpriteInBox(false, EXTRADATA(node).background, SPRITE_STATUS_NORMAL, pos[0], pos[1], node->box.size[0], node->box.size[1]);
	}

	font = UI_GetFontFromNode(node);

	lineHeight =  EXTRADATA(node).lineHeight;
	if (lineHeight == 0)
		lineHeight = UI_FontGetHeight(font);
	currentY = pos[1] + node->padding;

	/* skip option over current position */
	option = UI_AbstractOptionGetFirstOption(node);
	while (option && count < EXTRADATA(node).scrollY.viewPos) {
		option = option->next;
		count++;
	}

	/* draw all available options for this selectbox */
	for (; option; option = option->next) {
		int decX = pos[0] + node->padding;
		/* outside the node */
		if (currentY + lineHeight > pos[1] + node->box.size[1] - node->padding) {
			count++;
			break;
		}

		/* draw the hover effect */
		if (OPTIONEXTRADATA(option).hovered)
			UI_DrawFill(pos[0] + node->padding, currentY, node->box.size[0] - node->padding - node->padding, lineHeight, node->color);

		/* text color */
		if (Q_streq(OPTIONEXTRADATA(option).value, ref)) {
			textColor = node->selectedColor;
		} else if (node->disabled || option->disabled) {
			textColor = node->disabledColor;
		} else if (option->color[3] == 0.0f) {
			textColor = node->color;
		} else {
			textColor = option->color;
		}

		if (OPTIONEXTRADATA(option).icon) {
			uiSpriteStatus_t iconStatus = SPRITE_STATUS_NORMAL;
			if (option->disabled)
				iconStatus = SPRITE_STATUS_DISABLED;
			R_Color(nullptr);
			UI_DrawSpriteInBox(OPTIONEXTRADATA(option).flipIcon, OPTIONEXTRADATA(option).icon, iconStatus, decX, currentY, OPTIONEXTRADATA(option).icon->size[0], lineHeight);
			decX += OPTIONEXTRADATA(option).icon->size[0] + lineHeight / 4;
		}

		/* print the option label */
		const char* label = CL_Translate(OPTIONEXTRADATA(option).label);

		R_Color(textColor);
		UI_DrawString(font, ALIGN_UL, decX, currentY,
			pos[0], node->box.size[0] - node->padding - node->padding,
			0, label, 0, 0, nullptr, false, LONGLINES_PRETTYCHOP);

		/* next entries' position */
		currentY += lineHeight;
		count++;
	}
	R_Color(nullptr);

	/* count number of options (current architecture doesn't allow to know if the data change) */
	for (; option; option = option->next) {
		count++;
	}

	if (EXTRADATA(node).count != count) {
		EXTRADATA(node).count = count;
	}

	UI_OptionListNodeUpdateScroll(node);
}
Beispiel #12
0
/**
 * @brief Renders text and images
 * @sa SEQ_InitStartup
 * @param[in] context Sequence context
 * @param[in] backgroundObjects if true, draw background objects, else display foreground objects
 */
static void SEQ_Render2D (sequenceContext_t* context, bool backgroundObjects)
{
	int height = 0;

	/* add texts */
	for (int i = 0; i < context->numObj2Ds; i++) {
		seq2D_t* s2d = &context->obj2Ds[i];
		if (!s2d->inuse)
			continue;
		if (backgroundObjects != s2d->inBackground)
			continue;

		if (s2d->relativePos && height > 0) {
			s2d->pos[1] += height;
			s2d->relativePos = false;
		}
		/* advance in time */
		for (int j = 0; j < 4; j++) {
			s2d->color[j] += cls.frametime * s2d->fade[j];
			if (s2d->color[j] < 0.0)
				s2d->color[j] = 0.0;
			else if (s2d->color[j] > 1.0)
				s2d->color[j] = 1.0;
		}
		for (int j = 0; j < 2; j++) {
			s2d->pos[j] += cls.frametime * s2d->speed[j];
			s2d->size[j] += cls.frametime * s2d->enlarge[j];
		}

		/* outside the screen? */
		/** @todo We need this check - but this does not work */
		/*if (s2d->pos[1] >= VID_NORM_HEIGHT || s2d->pos[0] >= VID_NORM_WIDTH)
			continue;*/

		/* render */
		R_Color(s2d->color);

		/* image can be background */
		if (s2d->image[0] != '\0') {
			const image_t* image = R_FindImage(s2d->image, it_pic);
			R_DrawImage(s2d->pos[0], s2d->pos[1], image);
		}

		/* bgcolor can be overlay */
		if (s2d->bgcolor[3] > 0.0)
			R_DrawFill(s2d->pos[0], s2d->pos[1], s2d->size[0], s2d->size[1], s2d->bgcolor);

		/* border */
		if (s2d->border > 0 && s2d->bordercolor[3] > 0.0)
			R_DrawRect(s2d->pos[0], s2d->pos[1], s2d->size[0], s2d->size[1], s2d->bordercolor, s2d->border, 0xFFFF);

		/* render */
		R_Color(s2d->color);

		/* gettext placeholder */
		if (s2d->text) {
			int maxWidth = (int) s2d->size[0];
			if (maxWidth <= 0)
				maxWidth = VID_NORM_WIDTH;
			height += UI_DrawString(s2d->font, s2d->align, s2d->pos[0], s2d->pos[1], s2d->pos[0], maxWidth, -1 /** @todo use this for some nice line spacing */, CL_Translate(s2d->text));
		}
	}
	R_Color(nullptr);
}
Beispiel #13
0
/**
 * @brief Handles line breaks and drawing for shared data id
 * @param[in] node The context node
 * @param[in] text The test to draw else nullptr
 * @param[in] list The test to draw else nullptr
 * @param[in] noDraw If true, calling of this function only update the cache (real number of lines)
 * @note text or list but be used, not both
 */
void uiTextNode::drawText (uiNode_t* node, const char* text, const linkedList_t* list, bool noDraw)
{
	static char textCopy[UI_TEXTNODE_BUFFERSIZE];
	char newFont[MAX_VAR];
	const char* oldFont = nullptr;
	vec4_t colorHover;
	vec4_t colorSelectedHover;
	char* cur, *tab, *end;
	int fullSizeY;
	const char* font = UI_GetFontFromNode(node);
	vec2_t pos;
	int x, y, width;
	int viewSizeY;

	UI_GetNodeAbsPos(node, pos);

	if (isSizeChange(node)) {
		int lineHeight = EXTRADATA(node).lineHeight;
		if (lineHeight == 0) {
			const char* font = UI_GetFontFromNode(node);
			lineHeight = UI_FontGetHeight(font);
		}
		viewSizeY = node->box.size[1] / lineHeight;
	} else {
		viewSizeY = EXTRADATA(node).super.scrollY.viewSize;
	}

	/* text box */
	x = pos[0] + node->padding;
	y = pos[1] + node->padding;
	width = node->box.size[0] - node->padding - node->padding;

	if (text) {
		Q_strncpyz(textCopy, text, sizeof(textCopy));
	} else if (list) {
		Q_strncpyz(textCopy, CL_Translate((const char*)list->data), sizeof(textCopy));
	} else
		return;	/**< Nothing to draw */

	cur = textCopy;

	/* Hover darkening effect for normal text lines. */
	VectorScale(node->color, 0.8, colorHover);
	colorHover[3] = node->color[3];

	/* Hover darkening effect for selected text lines. */
	VectorScale(node->selectedColor, 0.8, colorSelectedHover);
	colorSelectedHover[3] = node->selectedColor[3];

	/* fix position of the start of the draw according to the align */
	switch (node->contentAlign % 3) {
	case 0:	/* left */
		break;
	case 1:	/* middle */
		x += width / 2;
		break;
	case 2:	/* right */
		x += width;
		break;
	}

	R_Color(node->color);

	fullSizeY = 0;
	do {
		bool haveTab;
		int x1; /* variable x position */
		/* new line starts from node x position */
		x1 = x;
		if (oldFont) {
			font = oldFont;
			oldFont = nullptr;
		}

		/* text styles and inline images */
		if (cur[0] == '^') {
			switch (toupper(cur[1])) {
			case 'B':
				Com_sprintf(newFont, sizeof(newFont), "%s_bold", font);
				oldFont = font;
				font = newFont;
				cur += 2; /* don't print the format string */
				break;
			}
		}

		/* get the position of the next newline - otherwise end will be null */
		end = strchr(cur, '\n');
		if (end)
			/* set the \n to \0 to draw only this part (before the \n) with our font renderer */
			/* let end point to the next char after the \n (or \0 now) */
			*end++ = '\0';

		/* highlighting */
		if (fullSizeY == EXTRADATA(node).textLineSelected && EXTRADATA(node).textLineSelected >= 0) {
			/* Draw current line in "selected" color (if the linenumber is stored). */
			R_Color(node->selectedColor);
		} else {
			R_Color(node->color);
		}

		if (node->state && EXTRADATA(node).mousefx && fullSizeY == EXTRADATA(node).lineUnderMouse) {
			/* Highlight line if mousefx is true. */
			/** @todo what about multiline text that should be highlighted completely? */
			if (fullSizeY == EXTRADATA(node).textLineSelected && EXTRADATA(node).textLineSelected >= 0) {
				R_Color(colorSelectedHover);
			} else {
				R_Color(colorHover);
			}
		}

		/* tabulation, we assume all the tabs fit on a single line */
		haveTab = strchr(cur, '\t') != nullptr;
		if (haveTab) {
			while (cur && *cur) {
				int tabwidth;

				tab = strchr(cur, '\t');

				/* use tab stop as given via property definition
				 * or use 1/3 of the node size (width) */
				if (!EXTRADATA(node).tabWidth)
					tabwidth = width / 3;
				else
					tabwidth = EXTRADATA(node).tabWidth;

				if (tab) {
					int numtabs = strspn(tab, "\t");
					tabwidth *= numtabs;
					while (*tab == '\t')
						*tab++ = '\0';
				} else {
					/* maximize width for the last element */
					tabwidth = width - (x1 - x);
					if (tabwidth < 0)
						tabwidth = 0;
				}

				/* minimize width for element outside node */
				if ((x1 - x) + tabwidth > width)
					tabwidth = width - (x1 - x);

				/* make sure it is positive */
				if (tabwidth < 0)
					tabwidth = 0;

				if (tabwidth != 0)
					UI_DrawString(font, (align_t)node->contentAlign, x1, y, x1, tabwidth - 1, EXTRADATA(node).lineHeight, cur, viewSizeY, EXTRADATA(node).super.scrollY.viewPos, &fullSizeY, false, LONGLINES_PRETTYCHOP);

				/* next */
				x1 += tabwidth;
				cur = tab;
			}
			fullSizeY++;
		}

		/*Com_Printf("until newline - lines: %i\n", lines);*/
		/* the conditional expression at the end is a hack to draw "/n/n" as a blank line */
		/* prevent line from being drawn if there is nothing that should be drawn after it */
		if (cur && (cur[0] || end || list)) {
			/* is it a white line? */
			if (!cur) {
				fullSizeY++;
			} else {
				if (noDraw) {
					int lines = 0;
					R_FontTextSize(font, cur, width, (longlines_t)EXTRADATA(node).longlines, nullptr, nullptr, &lines, nullptr);
					fullSizeY += lines;
				} else
					UI_DrawString(font, (align_t)node->contentAlign, x1, y, x, width, EXTRADATA(node).lineHeight, cur, viewSizeY, EXTRADATA(node).super.scrollY.viewPos, &fullSizeY, true, (longlines_t)EXTRADATA(node).longlines);
			}
		}

		if (EXTRADATA(node).mousefx)
			R_Color(node->color); /* restore original color */

		/* now set cur to the next char after the \n (see above) */
		cur = end;
		if (!cur && list) {
			list = list->next;
			if (list) {
				Q_strncpyz(textCopy, CL_Translate((const char*)list->data), sizeof(textCopy));
				cur = textCopy;
			}
		}
	} while (cur);

	/* update scroll status */
	setScrollY(node, -1, viewSizeY, fullSizeY);

	R_Color(nullptr);
}
Beispiel #14
0
void uiSelectBoxNode::drawOverWindow (uiNode_t* node)
{
	const char* ref = UI_AbstractOptionGetCurrentValue(node);
	if (ref == nullptr)
		return;

	vec2_t nodepos;
	UI_GetNodeAbsPos(node, nodepos);

	const char* imageName = UI_GetReferenceString(node, node->image);
	if (!imageName)
		imageName = "ui/selectbox";

	const image_t* image = UI_LoadImage(imageName);

	const char* font = UI_GetFontFromNode(node);
	int selBoxX = nodepos[0] + SELECTBOX_SIDE_WIDTH;
	int selBoxY = nodepos[1] + SELECTBOX_SPACER;

	selBoxY += node->box.size[1];

	/* drop down list */
	/* left side */
	UI_DrawNormImage(false, nodepos[0], nodepos[1] + node->box.size[1], SELECTBOX_SIDE_WIDTH, node->box.size[1] * EXTRADATA(node).count,
		7.0f, 28.0f, 0.0f, 21.0f, image);

	/* stretched middle bar */
	UI_DrawNormImage(false, nodepos[0] + SELECTBOX_SIDE_WIDTH, nodepos[1] + node->box.size[1], node->box.size[0] -SELECTBOX_SIDE_WIDTH-SELECTBOX_RIGHT_WIDTH, node->box.size[1] * EXTRADATA(node).count,
		16.0f, 28.0f, 7.0f, 21.0f, image);

	/* right side */
	UI_DrawNormImage(false, nodepos[0] + node->box.size[0] -SELECTBOX_SIDE_WIDTH-SELECTBOX_RIGHT_WIDTH, nodepos[1] + node->box.size[1], SELECTBOX_SIDE_WIDTH, node->box.size[1] * EXTRADATA(node).count,
		23.0f, 28.0f, 16.0f, 21.0f, image);

	/* now draw all available options for this selectbox */
	int check = 0;
	for (uiNode_t* option = UI_AbstractOptionGetFirstOption(node); option; option = option->next) {
		if (option->invis)
			continue;
		/* draw the hover effect */
		if (OPTIONEXTRADATA(option).hovered)
			UI_DrawFill(selBoxX, selBoxY, node->box.size[0] -SELECTBOX_SIDE_WIDTH - SELECTBOX_SIDE_WIDTH - SELECTBOX_RIGHT_WIDTH,
					SELECTBOX_DEFAULT_HEIGHT, node->color);
		/* print the option label */
		const char* label = CL_Translate(OPTIONEXTRADATA(option).label);
		UI_DrawString(font, ALIGN_UL, selBoxX, selBoxY,
			selBoxX, node->box.size[0] - 4,
			0, label, 0, 0, nullptr, false, LONGLINES_PRETTYCHOP);
		/* next entries' position */
		selBoxY += node->box.size[1];
		check++;
	}

	/** detect inconsistency */
	if (check != EXTRADATA(node).count) {
		/** force clean up cache */
		Com_Printf("uiSelectBoxNode::drawOverWindow: Node '%s' contains unsynchronized option list. Fixed.\n", UI_GetPath(node));
		EXTRADATA(node).versionId = 0;
	}

	/* left side */
	UI_DrawNormImage(false, nodepos[0], selBoxY - SELECTBOX_SPACER, SELECTBOX_SIDE_WIDTH, SELECTBOX_BOTTOM_HEIGHT,
		7.0f, 32.0f, 0.0f, 28.0f, image);

	/* stretched middle bar */
	UI_DrawNormImage(false, nodepos[0] + SELECTBOX_SIDE_WIDTH, selBoxY - SELECTBOX_SPACER, node->box.size[0] - SELECTBOX_SIDE_WIDTH - SELECTBOX_RIGHT_WIDTH,
			SELECTBOX_BOTTOM_HEIGHT,
		16.0f, 32.0f, 7.0f, 28.0f, image);

	/* right bottom side */
	UI_DrawNormImage(false, nodepos[0] + node->box.size[0] - SELECTBOX_SIDE_WIDTH - SELECTBOX_RIGHT_WIDTH, selBoxY - SELECTBOX_SPACER,
		SELECTBOX_SIDE_WIDTH, SELECTBOX_BOTTOM_HEIGHT,
		23.0f, 32.0f, 16.0f, 28.0f, image);
}
Beispiel #15
0
void uiTabNode::draw (uiNode_t *node)
{
	ui_tabStatus_t lastStatus = UI_TAB_NOTHING;
	uiNode_t* option;
	uiNode_t* overMouseOption = NULL;
	const char *ref;
	const char *font;
	int currentX;
	int allowedWidth;
	vec2_t pos;

	const char* image = UI_GetReferenceString(node, node->image);
	if (!image)
		image = "ui/tab";

	ref = UI_AbstractOptionGetCurrentValue(node);
	if (ref == NULL)
		return;

	font = UI_GetFontFromNode(node);

	if (node->state) {
		overMouseOption = UI_TabNodeTabAtPosition(node, mousePosX, mousePosY);
	}

	UI_GetNodeAbsPos(node, pos);
	currentX = pos[0];
	option = node->firstChild;
	assert(option->behaviour == ui_optionBehaviour);
	/** @todo this dont work when an option is hidden */
	allowedWidth = node->box.size[0] - TILE_WIDTH * (EXTRADATA(node).count + 1);

	while (option) {
		int fontHeight;
		int fontWidth;
		int tabWidth;
		int textPos;
		bool drawIcon = false;
		ui_tabStatus_t status = UI_TAB_NORMAL;
		assert(option->behaviour == ui_optionBehaviour);

		/* skip hidden options */
		if (option->invis) {
			option = option->next;
			continue;
		}

		/* Check the status of the current tab */
		if (Q_streq(OPTIONEXTRADATA(option).value, ref)) {
			status = UI_TAB_SELECTED;
		} else if (option->disabled || node->disabled) {
			status = UI_TAB_DISABLED;
		} else if (option == overMouseOption) {
			status = UI_TAB_HIGHLIGHTED;
		}

		/* Display */
		UI_TabNodeDrawJunction(image, currentX, pos[1], lastStatus, status);
		currentX += TILE_WIDTH;

		const char *label = CL_Translate(OPTIONEXTRADATA(option).label);

		R_FontTextSize(font, label, 0, LONGLINES_PRETTYCHOP, &fontWidth, &fontHeight, NULL, NULL);
		tabWidth = fontWidth;
		if (OPTIONEXTRADATA(option).icon && OPTIONEXTRADATA(option).icon->size[0] < allowedWidth) {
			tabWidth += OPTIONEXTRADATA(option).icon->size[0];
			drawIcon = true;
		}
		if (tabWidth > allowedWidth) {
			if (allowedWidth > 0)
				tabWidth = allowedWidth;
			else
				tabWidth = 0;
		}

		if (tabWidth > 0) {
			UI_TabNodeDrawPlain(image, currentX, pos[1], tabWidth, status);
		}

		textPos = currentX;
		if (drawIcon) {
			uiSpriteStatus_t iconStatus = SPRITE_STATUS_NORMAL;
			if (status == UI_TAB_DISABLED) {
				iconStatus = SPRITE_STATUS_DISABLED;
			}
			UI_DrawSpriteInBox(OPTIONEXTRADATA(option).flipIcon, OPTIONEXTRADATA(option).icon, iconStatus, currentX, pos[1], OPTIONEXTRADATA(option).icon->size[0], TILE_HEIGHT);
			textPos += OPTIONEXTRADATA(option).icon->size[0];
		}

		/** @todo fontWidth can be =0, maybe a bug from the font cache */
		OPTIONEXTRADATA(option).truncated = tabWidth < fontWidth || tabWidth == 0;
		UI_DrawString(font, ALIGN_UL, textPos, pos[1] + ((node->box.size[1] - fontHeight) / 2),
			textPos, tabWidth + 1, 0, label, 0, 0, NULL, false, LONGLINES_PRETTYCHOP);
		currentX += tabWidth;
		allowedWidth -= tabWidth;

		/* Next */
		lastStatus = status;
		option = option->next;
	}

	/* Display last junction and end of header */
	UI_TabNodeDrawJunction(image, currentX, pos[1], lastStatus, UI_TAB_NOTHING);
	currentX += TILE_WIDTH;
	if (currentX < pos[0] + node->box.size[0])
		UI_TabNodeDrawPlain(image, currentX, pos[1], pos[0] + node->box.size[0] - currentX, UI_TAB_NOTHING);
}
Beispiel #16
0
const char* UI_GetText (int textId)
{
	if (ui_global.sharedData[textId].type != UI_SHARED_TEXT)
		return nullptr;
	return CL_Translate(ui_global.sharedData[textId].data.text);
}
Beispiel #17
0
void uiOptionTreeNode::draw (uiNode_t *node)
{
	uiNode_t* option;
	const char *ref;
	const char *font;
	vec2_t pos;
	int fontHeight;
	int currentY;
	int currentDecY = 0;
	const float *textColor;
	vec4_t disabledColor = {0.5, 0.5, 0.5, 1.0};
	int count = 0;
	uiOptionIterator_t iterator;

	if (!systemExpand)
		systemExpand = UI_GetSpriteByName("icons/system_expand");
	if (!systemCollapse)
		systemCollapse = UI_GetSpriteByName("icons/system_collapse");

	ref = UI_AbstractOptionGetCurrentValue(node);
	if (ref == NULL)
		return;

	UI_GetNodeAbsPos(node, pos);

	if (EXTRADATA(node).background) {
		UI_DrawSpriteInBox(false, EXTRADATA(node).background, SPRITE_STATUS_NORMAL, pos[0], pos[1], node->box.size[0], node->box.size[1]);
	}

	font = UI_GetFontFromNode(node);
	fontHeight = EXTRADATA(node).lineHeight;
	currentY = pos[1] + node->padding;
	if (fontHeight == 0)
		fontHeight = UI_FontGetHeight(font);
	else {
		const int height = UI_FontGetHeight(font);
		currentDecY = (fontHeight - height) / 2;
	}

	/* skip option over current position */
	option = UI_OptionTreeNodeGetFirstOption(node);
	UI_OptionTreeNodeUpdateScroll(node);
	option = UI_InitOptionIteratorAtIndex(EXTRADATA(node).scrollY.viewPos, option, &iterator);

	/* draw all available options for this selectbox */
	for (; option; option = UI_OptionIteratorNextOption(&iterator)) {
		int decX;

		/* outside the node */
		if (currentY + fontHeight > pos[1] + node->box.size[1] - node->padding) {
			count++;
			break;
		}

		/* draw the hover effect */
		if (OPTIONEXTRADATA(option).hovered)
			UI_DrawFill(pos[0] + node->padding, currentY, node->box.size[0] - node->padding - node->padding, fontHeight, node->color);

		/* text color */
		if (Q_streq(OPTIONEXTRADATA(option).value, ref)) {
			textColor = node->selectedColor;
		} else if (node->disabled || option->disabled) {
			textColor = disabledColor;
		} else if (option->color[3] == 0.0f) {
			textColor = node->color;
		} else {
			textColor = option->color;
		}

		/* print the option label */
		decX = pos[0] + node->padding + iterator.depthPos * DEPTH_WIDTH;

		R_Color(NULL);
		if (option->firstChild) {
			uiSprite_t *icon = OPTIONEXTRADATA(option).collapsed ? systemExpand : systemCollapse;
			UI_DrawSpriteInBox(OPTIONEXTRADATA(option).flipIcon, icon, SPRITE_STATUS_NORMAL, decX, currentY, icon->size[0], fontHeight);
		}

		decX += COLLAPSEBUTTON_WIDTH;

		if (OPTIONEXTRADATA(option).icon) {
			uiSpriteStatus_t iconStatus = SPRITE_STATUS_NORMAL;
			if (option->disabled)
				iconStatus = SPRITE_STATUS_DISABLED;
			UI_DrawSpriteInBox(OPTIONEXTRADATA(option).flipIcon, OPTIONEXTRADATA(option).icon, iconStatus, decX, currentY,
					OPTIONEXTRADATA(option).icon->size[0], fontHeight);
			decX += OPTIONEXTRADATA(option).icon->size[0] + fontHeight / 4;
		}

		const char *label = CL_Translate(OPTIONEXTRADATA(option).label);

		R_Color(textColor);
		UI_DrawString(font, ALIGN_UL, decX, currentY + currentDecY,
			pos[0], node->box.size[0] - node->padding - node->padding,
			0, label, 0, 0, NULL, false, LONGLINES_PRETTYCHOP);

		/* next entries' position */
		currentY += fontHeight;
		count++;
	}
	R_Color(NULL);
}