Example #1
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);
}
Example #2
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);
	}
}
Example #3
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();
}
Example #4
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);
}
/**
 * @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);
}
Example #6
0
/**
 * @brief Handles tab clicks
 */
void uiTabNode::onLeftClick (uiNode_t* node, int x, int y)
{
	uiNode_t* option;

	if (UI_AbstractOptionGetCurrentValue(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_AbstractOptionSetCurrentValue(node, OPTIONEXTRADATA(option).value);

	UI_PlaySound("click1");
}
Example #7
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);
}
Example #8
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);
}
Example #9
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);
}
Example #10
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);
}
Example #11
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);
}
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);
}