예제 #1
0
파일: ui_data.c 프로젝트: chrisglass/ufoai
/**
 * @brief Initializes an option with a very little set of values.
 * @param[in] option Context option
 * @param[in] label label displayed
 * @param[in] value value used when this option is selected
 */
static void UI_InitOption (uiNode_t* option, const char* label, const char* value)
{
	assert(option);
	assert(option->behaviour == ui_optionBehaviour);
	Q_strncpyz(OPTIONEXTRADATA(option).label, label, sizeof(OPTIONEXTRADATA(option).label));
	Q_strncpyz(OPTIONEXTRADATA(option).value, value, sizeof(OPTIONEXTRADATA(option).value));
}
예제 #2
0
파일: ui_data.cpp 프로젝트: chagara/ufoai
/**
 * @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;
	}
}
예제 #3
0
/**
 * @brief Handles selectboxes clicks
 */
static void UI_OptionTreeNodeClick (uiNode_t * node, int x, int y)
{
	uiNode_t* option;
	int depth;

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

	/* select the right option */
	option = UI_OptionTreeNodeGetOptionAtPosition(node, x, y, &depth);

	UI_NodeAbsoluteToRelativePos(node, &x, &y);

	/* extend/collapse*/
	x -= depth * DEPTH_WIDTH;
	if (x >= 0 && x < COLLAPSEBUTTON_WIDTH) {
		if (option && option->firstChild) {
			OPTIONEXTRADATA(option).collapsed = !OPTIONEXTRADATA(option).collapsed;
			UI_OptionTreeNodeUpdateCache(node);
		}
		return;
	}

	/* update the status */
	if (option)
		UI_AbstractOptionSetCurrentValue(node, OPTIONEXTRADATA(option).value);
}
예제 #4
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);
	}
}
예제 #5
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->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->size[0] || y >= node->size[1])
        return NULL;

    font = UI_GetFontFromNode(node);

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

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

        if (x < TILE_WIDTH / 2)
            return prev;

        label = OPTIONEXTRADATA(option).label;
        if (label[0] == '_')
            label = _(label + 1);

        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;
}
예제 #6
0
static void UI_OptionTreeSetSelectedValue (uiNode_t *node, const uiCallContext_t *context)
{
	uiOptionIterator_t iterator;
	uiNode_t *option;
	uiNode_t *firstOption;
	const char* value;
	int pos, i;

	if (UI_GetParamNumber(context) != 1) {
		Com_Printf("UI_OptionTreeSetSelectedValue: Invalide number of param\n");
		return;
	}

	value = UI_GetParam(context, 1);

	/* is the option exists */
	firstOption = UI_OptionTreeNodeGetFirstOption(node);
	UI_InitOptionIteratorAtIndex(0, firstOption, &iterator);
	/** @todo merge that into the Init iterator function */
	iterator.skipCollapsed = qfalse;
	option = UI_FindOptionByValue(&iterator, value);

	/* update the selection */
	if (option) {
		UI_AbstractOptionSetCurrentValue(node, OPTIONEXTRADATA(option).value);
	} else {
		Com_Printf("UI_OptionTreeSetSelectedValue: Option value \"%s\" not found\n", value);
		return;
	}

	/* expend parents */
	for (i = 0; i < iterator.depthPos; i++)
		OPTIONEXTRADATA(iterator.depthCache[i]).collapsed = qfalse;
	UI_OptionTreeNodeUpdateCache(node);
	UI_OptionTreeNodeUpdateScroll(node);

	/* fix scroll bar */
	firstOption = UI_OptionTreeNodeGetFirstOption(node);
	UI_InitOptionIteratorAtIndex(0, firstOption, &iterator);
	pos = UI_FindOptionPosition(&iterator, option);
	if (pos == -1)
		return;
	if (pos < EXTRADATA(node).scrollY.viewPos || pos >= EXTRADATA(node).scrollY.viewPos + EXTRADATA(node).scrollY.viewSize) {
		qboolean updated;
		updated = UI_SetScroll(&EXTRADATA(node).scrollY, pos, -1, -1);
		if (updated && EXTRADATA(node).onViewChange)
			UI_ExecuteEventActions(node, EXTRADATA(node).onViewChange);
	}
}
예제 #7
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);
}
예제 #8
0
/** called when the window is pushed
 * check cvar then, reduce runtime check
 * @todo move cvar check to AbstractOption
 */
static void UI_TabNodeInit (uiNode_t *node, linkedList_t *params)
{
    const char *cvarName;

    /* no cvar given? */
    if (!(EXTRADATA(node).cvar))
        return;

    /* not a cvar? */
    if (!Q_strstart(EXTRADATA(node).cvar, "*cvar:")) {
        /* normalize */
        Com_Printf("UI_TabNodeInit: node '%s' doesn't have a valid cvar assigned (\"%s\" read)\n", UI_GetPath(node), EXTRADATA(node).cvar);
        EXTRADATA(node).cvar = NULL;
        return;
    }

    /* cvar do not exists? */
    cvarName = &EXTRADATA(node).cvar[6];
    if (Cvar_FindVar(cvarName) == NULL) {
        /* search default value, if possible */
        uiNode_t* option = node->firstChild;
        assert(option->behaviour == ui_optionBehaviour);
        Cvar_ForceSet(cvarName, OPTIONEXTRADATA(option).value);
    }
}
예제 #9
0
파일: ui_data.c 프로젝트: chrisglass/ufoai
/**
 * @brief Find the next element from the iterator
 * Iterator skipCollapsed and skipInvisible attribute can control the option flow
 */
uiNode_t* UI_OptionIteratorNextOption (uiOptionIterator_t* iterator)
{
	uiNode_t* option;

	option = iterator->option;
	assert(iterator->depthPos < MAX_DEPTH_OPTIONITERATORCACHE);
	iterator->depthCache[iterator->depthPos] = option;
	iterator->depthPos++;

	if (OPTIONEXTRADATA(option).collapsed && iterator->skipCollapsed)
		option = NULL;
	else
		option = option->firstChild;

	while (qtrue) {
		while (option) {
			if (!option->invis || !iterator->skipInvisible) {
				iterator->option = option;
				return option;
			}
			option = option->next;
		}
		if (iterator->depthPos == 0)
			break;
		iterator->depthPos--;
		option = iterator->depthCache[iterator->depthPos]->next;
	}

	iterator->option = NULL;
	return NULL;
}
예제 #10
0
파일: ui_data.c 프로젝트: chrisglass/ufoai
/**
 * @brief Find an option (and all his parents) by is value.
 * @param[in,out] iterator If it found an option, the iterator contain all option parent
 * @param[in] value The value we search
 * @return The right option, else NULL
 */
uiNode_t* UI_FindOptionByValue (uiOptionIterator_t* iterator, const char* value)
{
	while (iterator->option) {
		assert(iterator->option->behaviour == ui_optionBehaviour);
		if (Q_streq(OPTIONEXTRADATA(iterator->option).value, value))
			return iterator->option;
		UI_OptionIteratorNextOption(iterator);
	}
	return NULL;
}
예제 #11
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
 */
static void UI_TabNodeDrawTooltip (uiNode_t *node, int x, int y)
{
    uiNode_t *option;
    const int tooltipWidth = 250;
    const char *label;

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

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

    label = OPTIONEXTRADATA(option).label;
    if (label[0] == '_')
        label = _(label + 1);

    UI_DrawTooltip(label, x, y, tooltipWidth);
}
예제 #12
0
/**
 * @brief Handles selectboxes clicks
 */
static void UI_SelectBoxNodeClick (uiNode_t *node, int x, int y)
{
	uiNode_t* option;
	int clickedAtOption;
	vec2_t pos;

	/* dropdown the node */
	if (UI_GetMouseCapture() == NULL) {
		UI_SetMouseCapture(node);
		return;
	}

	UI_GetNodeAbsPos(node, pos);
	clickedAtOption = (y - pos[1]);

	/* we click outside */
	if (x < pos[0] || y < pos[1] || x >= pos[0] + node->size[0] || y >= pos[1] + node->size[1] * (EXTRADATA(node).count + 1)) {
		UI_MouseRelease();
		return;
	}

	/* we click on the head */
	if (clickedAtOption < node->size[1]) {
		UI_MouseRelease();
		return;
	}

	clickedAtOption = (clickedAtOption - node->size[1]) / node->size[1];
	if (clickedAtOption < 0 || clickedAtOption >= EXTRADATA(node).count)
		return;

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

	/* select the right option */
	option = UI_AbstractOptionGetFirstOption(node);
	for (; option; option = option->next) {
		if (option->invis)
			continue;
		if (clickedAtOption == 0)
			break;
		clickedAtOption--;
	}

	/* update the status */
	if (option)
		UI_AbstractOptionSetCurrentValue(node, OPTIONEXTRADATA(option).value);

	/* close the dropdown */
	UI_MouseRelease();
}
예제 #13
0
파일: ui_data.c 프로젝트: chrisglass/ufoai
/**
 * @brief find an option why index (0 is the first option)
 * @param[in] index Requested index (0 is the first option)
 * @param[in] option First element of options (it can be a tree)
 * @param[in,out] iterator need an initialised iterator, and update it into the write index
 */
static uiNode_t* UI_FindOptionAtIndex (int index, uiNode_t* option, uiOptionIterator_t* iterator)
{
	while (option) {
		assert(option->behaviour == ui_optionBehaviour);
		if (option->invis) {
			option = option->next;
			continue;
		}

		/* we are on the right element */
		if (index == 0) {
			iterator->option = option;
			return option;
		}

		/* not the parent */
		index--;

		if (OPTIONEXTRADATA(option).collapsed) {
			option = option->next;
			continue;
		}

		/* its a child */
		if (index < OPTIONEXTRADATA(option).childCount) {
			if (iterator->depthPos >= MAX_DEPTH_OPTIONITERATORCACHE)
				assert(qfalse);
			iterator->depthCache[iterator->depthPos] = option;
			iterator->depthPos++;
			return UI_FindOptionAtIndex(index, option->firstChild, iterator);
		}
		index -= OPTIONEXTRADATA(option).childCount;
		option = option->next;
	}

	iterator->option = NULL;
	return NULL;
}
예제 #14
0
/**
 * @brief Handles selectboxes clicks
 */
void uiOptionListNode::onLeftClick (uiNode_t* node, int x, int y)
{
	uiNode_t* option;

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

	/* select the right option */
	option = UI_OptionListNodeGetOptionAtPosition(node, x, y);

	/* update the status */
	if (option)
		UI_AbstractOptionSetCurrentValue(node, OPTIONEXTRADATA(option).value);
}
예제 #15
0
/**
 * @brief update option cache about child, according to collapse and visible status
 * @note can be a common function for all option node
 * @return number of visible elements
 */
int UI_OptionUpdateCache (uiNode_t* option)
{
	int count = 0;
	while (option) {
		int localCount = 0;
		assert(option->behaviour == ui_optionBehaviour);
		if (option->invis) {
			option = option->next;
			continue;
		}
		if (OPTIONEXTRADATA(option).collapsed) {
			OPTIONEXTRADATA(option).childCount = 0;
			option = option->next;
			count++;
			continue;
		}
		if (option->firstChild)
			localCount = UI_OptionUpdateCache(option->firstChild);
		OPTIONEXTRADATA(option).childCount = localCount;
		count += 1 + localCount;
		option = option->next;
	}
	return count;
}
/**
 * @brief Function for menu buttons to update message settings.
 * @sa MSO_Set
 * @todo move this into scripts
 */
static void MSO_Toggle_f (void)
{
	if (cgi->Cmd_Argc() != 3)
		Com_Printf("Usage: %s <listId> <pause|notify|sound>\n", cgi->Cmd_Argv(0));
	else {
		uiOptionIterator_t iterator;
		const int listIndex = atoi(cgi->Cmd_Argv(1));
		int idx;
		const msgCategoryEntry_t* selectedEntry;
		int optionType;
		bool activate;
		int type;
		uiNode_t* messageSetting = cgi->UI_GetOption(TEXT_MESSAGEOPTIONS);

		UI_InitOptionIteratorAtIndex(messageList_scroll + listIndex, messageSetting, &iterator);
		if (!iterator.option)
			return;

		idx = atoi(OPTIONEXTRADATA(iterator.option).value);
		selectedEntry = &ccs.msgCategoryEntries[idx];
		if (!selectedEntry)
			return;
		if (selectedEntry->isCategory) {
			Com_Printf("Toggle command with selected category entry ignored.\n");
			return;
		}
		for (type = 0; type < NT_NUM_NOTIFYTYPE; type++) {
			if (Q_streq(nt_strings[type], selectedEntry->notifyType))
				break;
		}
		if (type == NT_NUM_NOTIFYTYPE) {
			Com_Printf("Unrecognized messagetype during toggle '%s' ignored\n", selectedEntry->notifyType);
			return;
		}

		if (Q_streq(cgi->Cmd_Argv(2), "pause")) {
			optionType = MSO_PAUSE;
			activate = !selectedEntry->settings->doPause;
		} else if (Q_streq(cgi->Cmd_Argv(2), "notify")) {
			optionType = MSO_NOTIFY;
			activate = !selectedEntry->settings->doNotify;
		} else {
			optionType = MSO_SOUND;
			activate = !selectedEntry->settings->doSound;
		}
		MSO_Set(listIndex, (notify_t)type, optionType, activate, true);
	}
}
예제 #17
0
/**
 * @brief call when the mouse move is the node is captured
 * @todo we can remove the loop if we save the current element in the node
 */
void uiSelectBoxNode::onCapturedMouseMove (uiNode_t* node, int x, int y)
{
	UI_NodeAbsoluteToRelativePos(node, &x, &y);

	/* test bounded box */
	if (x < 0 || y < 0 || x > node->box.size[0] || y > node->box.size[1] * (EXTRADATA(node).count + 1)) {
		return;
	}

	int posy = node->box.size[1];
	for (uiNode_t* option = UI_AbstractOptionGetFirstOption(node); option; option = option->next) {
		if (option->invis)
			continue;
		OPTIONEXTRADATA(option).hovered = (posy <= y && y < posy + node->box.size[1]);
		posy += node->box.size[1];
	}
}
예제 #18
0
static void CL_SetRatioFilter_f (void)
{
	uiNode_t* firstOption = UI_GetOption(OPTION_VIDEO_RESOLUTIONS);
	uiNode_t* option = firstOption;
	float requestedRation = atof(Cmd_Argv(1));
	bool all = false;
	bool custom = false;
	const float delta = 0.01;

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

	if (Q_streq(Cmd_Argv(1), "all"))
		all = true;
	else if (Q_streq(Cmd_Argv(1), "custom"))
		custom = true;
	else
		requestedRation = atof(Cmd_Argv(1));

	while (option) {
		int width;
		int height;
		bool visible = false;
		const int result = sscanf(OPTIONEXTRADATA(option).label, "%i x %i", &width, &height);
		if (result != 2)
			Com_Error(ERR_FATAL, "CL_SetRatioFilter_f: Impossible to decode resolution label.\n");
		const float ratio = (float)width / (float)height;

		if (all)
			visible = true;
		else if (custom)
			/** @todo We should check the ratio list and remove matched resolutions, here it is a hack */
			visible = ratio > 2 || (ratio > 1.7 && ratio < 1.76);
		else
			visible = ratio - delta < requestedRation && ratio + delta > requestedRation;

		option->invis = !visible;
		option = option->next;
	}

	/* the content change */
	UI_RegisterOption(OPTION_VIDEO_RESOLUTIONS, firstOption);
}
예제 #19
0
/**
 * @brief Handles tab clicks
 */
static void UI_TabNodeClick (uiNode_t * node, int x, int y)
{
    uiNode_t* option;

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

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

    if (option->disabled)
        return;

    /* only execute the click stuff if the selectbox is active */
    if (node->state)
        UI_AbstractOptionSetCurrentValue(node, OPTIONEXTRADATA(option).value);
}
예제 #20
0
파일: cp_ufopedia.cpp 프로젝트: cigo/ufoai
/**
 * @brief Generate a tree of option for all allowed chapters and articles
 * @note it update OPTION_UFOPEDIA
 */
static void UP_GenerateSummary (void)
{
	uiNode_t* chapters = nullptr;
	int num = 0;

	numChaptersDisplayList = 0;

	for (int i = 0; i < ccs.numChapters; i++) {
		/* hide chapters without name */
		pediaChapter_t* chapter = &ccs.upChapters[i];
		if (chapter->name == nullptr)
			continue;

		/* Check if there are any researched or collected items in this chapter ... */
		bool researchedEntries = false;
		upCurrentTech = chapter->first;
		while (upCurrentTech) {
			if (UP_TechGetsDisplayed(upCurrentTech)) {
				researchedEntries = true;
				break;
			}
			upCurrentTech = upCurrentTech->upNext;
		}

		/* .. and if so add them to the displaylist of chapters. */
		if (researchedEntries) {
			uiNode_t* chapterOption;
			if (numChaptersDisplayList >= sizeof(upChaptersDisplayList))
				cgi->Com_Error(ERR_DROP, "MAX_PEDIACHAPTERS hit");
			upChaptersDisplayList[numChaptersDisplayList++] = chapter;

			/* chapter section*/
			chapterOption = cgi->UI_AddOption(&chapters, chapter->id, va("_%s", chapter->name), va("%i", num));
			/** @todo use a confunc */
			OPTIONEXTRADATA(chapterOption).icon = cgi->UI_GetSpriteByName(va("icons/ufopedia_%s", chapter->id));
			chapterOption->firstChild = UP_GenerateArticlesSummary(chapter);

			num++;
		}
	}

	cgi->UI_RegisterOption(OPTION_UFOPEDIA, chapters);
	cgi->Cvar_Set("mn_uptitle", _("UFOpaedia"));
}
예제 #21
0
파일: ui_node_tab.cpp 프로젝트: yason/ufoai
/**
 * @brief Handles tab clicks
 */
void uiTabNode::onLeftClick (uiNode_t* node, int x, int y)
{
	uiNode_t* option;

	if (UI_AbstractOption_GetCurrentValue(node) == nullptr)
		return;

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

	if (option->disabled)
		return;

	/* only execute the click stuff if the selectbox is active */
	if (node->state)
		UI_AbstractOption_SetCurrentValue(node, OPTIONEXTRADATA(option).value);

	UI_PlaySound("click1");
}
예제 #22
0
파일: ui_node_tab.cpp 프로젝트: yason/ufoai
/** called when the window is pushed
 * check cvar then, reduce runtime check
 * @todo move cvar check to AbstractOption
 */
void uiTabNode::onWindowOpened (uiNode_t* node, linkedList_t* params)
{
	/* no cvar given? */
	if (!(EXTRADATA(node).cvar))
		return;

	/* not a cvar? */
	char const* const cvarName = Q_strstart(EXTRADATA(node).cvar, "*cvar:");
	if (!cvarName) {
		/* normalize */
		Com_Printf("UI_TabNodeInit: node '%s' doesn't have a valid cvar assigned (\"%s\" read)\n", UI_GetPath(node), EXTRADATA(node).cvar);
		EXTRADATA(node).cvar = nullptr;
		return;
	}

	/* cvar does not exist? */
	if (Cvar_FindVar(cvarName) == nullptr) {
		/* search default value, if possible */
		uiNode_t* option = node->firstChild;
		assert(option->behaviour == ui_optionBehaviour);
		Cvar_ForceSet(cvarName, OPTIONEXTRADATA(option).value);
	}
}
예제 #23
0
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);
}
static void UI_OptionListNodeDraw (uiNode_t *node)
{
	static const int panelTemplate[] = {
		CORNER_SIZE, MID_SIZE, CORNER_SIZE,
		CORNER_SIZE, MID_SIZE, CORNER_SIZE,
		MARGE
	};
	uiNode_t* option;
	const char *ref;
	const char *font;
	int lineHeight;
	vec2_t pos;
	const char* image;
	int currentY;
	const float *textColor;
	static vec4_t disabledColor = {0.5, 0.5, 0.5, 1.0};
	int count = 0;

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

	UI_GetNodeAbsPos(node, pos);

	image = UI_GetReferenceString(node, node->image);
	if (image)
		UI_DrawPanel(pos, node->size, image, 0, 0, panelTemplate);

	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) {
		const char *label;
		int decX = pos[0] + node->padding;
		/* outside the node */
		if (currentY + lineHeight > pos[1] + node->size[1] - node->padding) {
			count++;
			break;
		}

		/* draw the hover effect */
		if (OPTIONEXTRADATA(option).hovered)
			UI_DrawFill(pos[0] + node->padding, currentY, node->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 = 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(NULL);
			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 */
		label = OPTIONEXTRADATA(option).label;
		if (label[0] == '_')
			label = _(label + 1);

		R_Color(textColor);
		UI_DrawString(font, ALIGN_UL, decX, currentY,
			pos[0], node->size[0] - node->padding - node->padding,
			0, label, 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);

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

	/* 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);
}
예제 #25
0
static void UI_OptionTreeNodeDraw (uiNode_t *node)
{
	static const int panelTemplate[] = {
		CORNER_SIZE, MID_SIZE, CORNER_SIZE,
		CORNER_SIZE, MID_SIZE, CORNER_SIZE,
		MARGE
	};
	uiNode_t* option;
	const char *ref;
	const char *font;
	vec2_t pos;
	const char* image;
	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);

	image = UI_GetReferenceString(node, node->image);
	if (image)
		UI_DrawPanel(pos, node->size, image, 0, 0, panelTemplate);

	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;
		const char *label;

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

		/* draw the hover effect */
		if (OPTIONEXTRADATA(option).hovered)
			UI_DrawFill(pos[0] + node->padding, currentY, node->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;
		}

		label = OPTIONEXTRADATA(option).label;
		if (label[0] == '_')
			label = _(label + 1);

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

		/* next entries' position */
		currentY += fontHeight;
		count++;
	}
	R_Color(NULL);
}
예제 #26
0
static void UI_SelectBoxNodeDrawOverWindow (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;

	ref = UI_AbstractOptionGetCurrentValue(node);
	if (ref == NULL)
		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;

	selBoxY += node->size[1];

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

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

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

	/* now draw all available options for this selectbox */
	for (option = UI_AbstractOptionGetFirstOption(node); option; option = option->next) {
		const char *label;
		if (option->invis)
			continue;
		/* draw the hover effect */
		if (OPTIONEXTRADATA(option).hovered)
			UI_DrawFill(selBoxX, selBoxY, node->size[0] -SELECTBOX_SIDE_WIDTH - SELECTBOX_SIDE_WIDTH - SELECTBOX_RIGHT_WIDTH,
					SELECTBOX_DEFAULT_HEIGHT, node->color);
		/* print the option label */
		label = OPTIONEXTRADATA(option).label;
		if (label[0] == '_')
			label = _(label + 1);
		UI_DrawString(font, ALIGN_UL, selBoxX, selBoxY,
			selBoxX, node->size[0] - 4,
			0, label, 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
		/* next entries' position */
		selBoxY += node->size[1];
	}
	/* left side */
	UI_DrawNormImage(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(nodepos[0] + SELECTBOX_SIDE_WIDTH, selBoxY - SELECTBOX_SPACER, node->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(nodepos[0] + node->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);
}
예제 #27
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);
}
예제 #28
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);
}