コード例 #1
0
ファイル: ui_node_sequence.cpp プロジェクト: AresAndy/ufoai
void uiSequenceNode::onWindowOpened (uiNode_t* node, linkedList_t* params)
{
	if (EXTRADATA(node).context == nullptr)
		EXTRADATA(node).context = SEQ_AllocContext();
	if (EXTRADATA(node).source != nullptr) {
		SEQ_InitContext(EXTRADATA(node).context, EXTRADATA(node).source);
		EXTRADATA(node).playing = true;
	}
}
コード例 #2
0
void uiBaseInventoryNode::onMouseDown (uiNode_t* node, int x, int y, int button)
{
	switch (button) {
	case K_MOUSE1:
	{
		/* start drag and drop */
		int fromX, fromY;
		dragInfoIC = UI_BaseInventoryNodeGetItem(node, x, y, &fromX, &fromY);
		if (dragInfoIC) {
			dragInfoFromX = fromX;
			dragInfoFromY = fromY;
			oldMouseX = x;
			oldMouseY = y;
			UI_SetMouseCapture(node);
			EXTRADATA(node).super.lastSelectedId = dragInfoIC->def()->idx;
			if (EXTRADATA(node).super.onSelect) {
				UI_ExecuteEventActions(node, EXTRADATA(node).super.onSelect);
			}
			if (EXTRADATA(node).super.lua_onSelect != LUA_NOREF) {
				UI_ExecuteLuaEventScript(node, EXTRADATA(node).super.lua_onSelect);
			}
		}
		break;
	}
	case K_MOUSE2:
		if (UI_DNDIsDragging()) {
			UI_DNDAbort();
		} else {
			/* auto place */
			UI_ContainerNodeAutoPlace(node, x, y);
		}
		break;
	default:
		break;
	}
}
コード例 #3
0
/**
 * Update the client zone
 */
static void UI_ClientLayout (uiNode_t *node)
{
	int width = 0;
	int height = 0;
	uiNode_t *child;
	qboolean updated;
	for (child = node->firstChild; child; child = child->next) {
		int value;
		value = child->pos[0] + child->size[0];
		if (value > width)
			width = value;
		value = child->pos[1] + child->size[1];
		if (value > height)
			height = value;
	}

	width += node->padding;
	height += node->padding;

	updated = UI_SetScroll(&EXTRADATA(node).super.scrollX, -1, node->size[0], width);
	updated = UI_SetScroll(&EXTRADATA(node).super.scrollY, -1, node->size[1], height) || updated;
	if (updated && EXTRADATA(node).super.onViewChange)
		UI_ExecuteEventActions(node, EXTRADATA(node).super.onViewChange);
}
コード例 #4
0
ファイル: ui_node_base.c プロジェクト: kevlund/ufoai
/**
 * @brief Draw a small square with the layout of the given base
 */
static void UI_BaseLayoutNodeDraw (uiNode_t * node)
{
	base_t *base;
	int height, width, y;
	int row, col;
	const vec4_t c_gray = {0.5, 0.5, 0.5, 1.0};
	vec2_t nodepos;
	int totalMarge;

	if (EXTRADATA(node).baseid >= MAX_BASES || EXTRADATA(node).baseid < 0)
		return;

	totalMarge = node->padding * (BASE_SIZE + 1);
	width = (node->size[0] - totalMarge) / BASE_SIZE;
	height = (node->size[1] - totalMarge) / BASE_SIZE;

	UI_GetNodeAbsPos(node, nodepos);

	base = B_GetBaseByIDX(EXTRADATA(node).baseid);

	y = nodepos[1] + node->padding;
	for (row = 0; row < BASE_SIZE; row++) {
		int x = nodepos[0] + node->padding;
		for (col = 0; col < BASE_SIZE; col++) {
			if (B_IsTileBlocked(base, col, row)) {
				UI_DrawFill(x, y, width, height, c_gray);
			} else if (B_GetBuildingAt(base, col, row) != NULL) {
				/* maybe destroyed in the meantime */
				if (base->founded)
					UI_DrawFill(x, y, width, height, node->color);
			}
			x += width + node->padding;
		}
		y += height + node->padding;
	}
}
コード例 #5
0
/**
 * @brief Handles selectboxes clicks
 */
void uiSelectBoxNode::onLeftClick (uiNode_t* node, int x, int y)
{
	/* dropdown the node */
	if (UI_GetMouseCapture() == nullptr) {
		UI_SetMouseCapture(node);
		return;
	}

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

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

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

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

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

	/* select the right option */
	uiNode_t* 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();
}
コード例 #6
0
static qboolean UI_RadioButtonNodeIsSelected (uiNode_t *node)
{
	if (EXTRADATA(node).string == NULL) {
		const float current = UI_GetReferenceFloat(node, EXTRADATA(node).cvar);
		return current > EXTRADATA(node).value - EPSILON && current < EXTRADATA(node).value + EPSILON;
	} else {
		const char *current = UI_GetReferenceString(node, EXTRADATA(node).cvar);
		return Q_streq(current, EXTRADATA(node).string);
	}
}
コード例 #7
0
/**
 * @brief Draws a base.
 */
void uiBaseMapNode::draw (uiNode_t * node)
{
	int col, row;
	bool hover = node->state;
	getCellAtPos(node, mousePosX, mousePosY, &col, &row);
	if (col == -1)
		hover = false;

	const int width = node->box.size[0] / BASE_SIZE;
	const int height = node->box.size[1] / BASE_SIZE + BASE_IMAGE_OVERLAY;

	vec2_t nodePos;
	UI_GetNodeAbsPos(node, nodePos);

	GAME_DrawBase(EXTRADATA(node).baseid, nodePos[0], nodePos[1], width, height, col, row, hover, BASE_IMAGE_OVERLAY);
}
コード例 #8
0
/**
 * @brief Called when the node lost the focus
 */
void uiTextEntryNode::onFocusLost (uiNode_t* node)
{
	/* already aborted/changed with the keyboard */
	if (editedCvar == nullptr)
		return;

	/* release the keyboard */
	if (isAborted || EXTRADATA(node).clickOutAbort) {
		UI_TextEntryNodeAbortEdition(node);
	} else {
		UI_TextEntryNodeValidateEdition(node);
	}
#if SDL_VERSION_ATLEAST(2,0,0)
	SDL_StopTextInput();
#endif
}
コード例 #9
0
ファイル: ui_node_text.cpp プロジェクト: XenderPL/ufoai
void uiTextNode::onLoaded (uiNode_t* node)
{
	int lineheight = EXTRADATA(node).lineHeight;
	/* auto compute lineheight */
	/* we don't overwrite EXTRADATA(node).lineHeight, because "0" is dynamically replaced by font height on draw function */
	if (lineheight == 0) {
		/* the font is used */
		const char* font = UI_GetFontFromNode(node);
		lineheight = UI_FontGetHeight(font);
	}

	/* auto compute rows (super.viewSizeY) */
	if (EXTRADATA(node).super.scrollY.viewSize == 0) {
		if (node->box.size[1] != 0 && lineheight != 0) {
			EXTRADATA(node).super.scrollY.viewSize = node->box.size[1] / lineheight;
		} else {
			EXTRADATA(node).super.scrollY.viewSize = 1;
			Com_Printf("UI_TextNodeLoaded: node '%s' has no rows value\n", UI_GetPath(node));
		}
	}

	/* auto compute height */
	if (node->box.size[1] == 0) {
		node->box.size[1] = EXTRADATA(node).super.scrollY.viewSize * lineheight;
	}

	/* is text slot exists */
	if (EXTRADATA(node).dataID >= UI_MAX_DATAID)
		Com_Error(ERR_DROP, "Error in node %s - max shared data id num exceeded (num: %i, max: %i)", UI_GetPath(node), EXTRADATA(node).dataID, UI_MAX_DATAID);

#ifdef DEBUG
	if (EXTRADATA(node).super.scrollY.viewSize != (int)(node->box.size[1] / lineheight)) {
		Com_Printf("UI_TextNodeLoaded: rows value (%i) of node '%s' differs from size (%.0f) and format (%i) values\n",
			EXTRADATA(node).super.scrollY.viewSize, UI_GetPath(node), node->box.size[1], lineheight);
	}
#endif

	if (node->text == nullptr && EXTRADATA(node).dataID == TEXT_NULL)
		Com_Printf("UI_TextNodeLoaded: 'textid' property of node '%s' is not set\n", UI_GetPath(node));
}
コード例 #10
0
ファイル: ui_node_vscrollbar.cpp プロジェクト: AresAndy/ufoai
/**
 * @brief Called when the node is captured by the mouse
 */
void uiVScrollbarNode::onCapturedMouseMove (uiNode_t* node, int x, int y)
{
	if (capturedElement != 2)
		return;

	const int posSize = EXTRADATA(node).fullsize;
	const int graphicSize = node->box.size[1] - (4 * ELEMENT_HEIGHT);

	/* compute mouse mouse */
	y -= oldMouseY;

	/* compute pos projection */
	const int pos = oldPos + (((float)y * (float)posSize) / (float)graphicSize);

	UI_VScrollbarNodeSet(node, pos);
}
コード例 #11
0
/**
 * @brief Draw the inventory of the base
 */
static void UI_BaseInventoryNodeDraw2 (uiNode_t* node, const objDef_t* highlightType)
{
	bool updateScroll = false;
	int visibleHeight = 0;
	int needHeight = 0;
	vec2_t screenPos;

	UI_GetNodeScreenPos(node, screenPos);
	UI_PushClipRect(screenPos[0], screenPos[1], node->box.size[0], node->box.size[1]);

	needHeight = UI_BaseInventoryNodeDrawItems(node, highlightType);

	UI_PopClipRect();
	visibleHeight = node->box.size[1];

#if 0
	R_FontDrawString("f_verysmall", ALIGN_UL,
		node->box.pos[0], node->box.pos[1], node->box.pos[0], node->box.pos[1],
		0,	0,	/* maxWidth/maxHeight */
		0, va("%i %i/%i", EXTRADATA(node).scrollCur, visibleRows, totalRows), 0, 0, nullptr, false, 0);
#endif

	/* Update display of scroll buttons if something changed. */
	if (visibleHeight != EXTRADATA(node).scrollY.viewSize || needHeight != EXTRADATA(node).scrollY.fullSize) {
		EXTRADATA(node).scrollY.fullSize = needHeight;
		EXTRADATA(node).scrollY.viewSize = visibleHeight;
		updateScroll = true;
	}
	if (EXTRADATA(node).scrollY.viewPos > needHeight - visibleHeight) {
		EXTRADATA(node).scrollY.viewPos = needHeight - visibleHeight;
		updateScroll = true;
	}
	if (EXTRADATA(node).scrollY.viewPos < 0) {
		EXTRADATA(node).scrollY.viewPos = 0;
		updateScroll = true;
	}

	if (updateScroll)
		UI_BaseInventoryNodeUpdateScroll(node);
}
コード例 #12
0
ファイル: ui_node_container.cpp プロジェクト: jklemmack/ufoai
/**
 * @brief Draw a grip container
 */
static void UI_ContainerNodeDrawGrid (uiNode_t *node, const objDef_t *highlightType)
{
	const invList_t *ic;
	vec3_t pos;

	UI_GetNodeAbsPos(node, pos);
	pos[2] = 0;

	for (ic = ui_inventory->c[EXTRADATA(node).container->id]; ic; ic = ic->next) {
		assert(ic->item.item);
		if (highlightType && INVSH_LoadableInWeapon(highlightType, ic->item.item))
			UI_DrawItem(node, pos, &ic->item, ic->x, ic->y, scale, colorLoadable);
		else
			UI_DrawItem(node, pos, &ic->item, ic->x, ic->y, scale, colorDefault);
	}
}
コード例 #13
0
/**
 * @brief Called before loading. Used to set default attribute values
 */
void uiGeoscapeNode::onLoading (uiNode_t* node)
{
    Vector4Set(node->color, 1, 1, 1, 1);

    OBJZERO(EXTRADATA(node));
    EXTRADATA(node).angles[YAW] = GLOBE_ROTATE;
    EXTRADATA(node).center[0] = EXTRADATA(node).center[1] = 0.5;
    EXTRADATA(node).zoom = 1.0;
    Vector2Set(EXTRADATA(node).smoothFinal2DGeoscapeCenter, 0.5, 0.5);
    VectorSet(EXTRADATA(node).smoothFinalGlobeAngle, 0, GLOBE_ROTATE, 0);

    /* @todo: allocate this on a per node basis - and remove the global variable geoscapeData */
    EXTRADATA(node).geoscapeData = &geoscapeData;
    /* EXTRADATA(node).geoscapeData = Mem_AllocType(geoscapeData_t); */

    /** this is the data that is used with r_dayandnightTexture */
    EXTRADATA(node).r_dayandnightAlpha = Mem_AllocTypeN(byte, DAN_WIDTH * DAN_HEIGHT);

    r_dayandnightTexture = R_LoadImageData("***r_dayandnighttexture***", nullptr, DAN_WIDTH, DAN_HEIGHT, it_effect);
    r_radarTexture = R_LoadImageData("***r_radarTexture***", nullptr, RADAR_WIDTH, RADAR_HEIGHT, it_effect);
    r_xviTexture = R_LoadImageData("***r_xvitexture***", nullptr, XVI_WIDTH, XVI_HEIGHT, it_effect);
}
コード例 #14
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];
	}
}
コード例 #15
0
ファイル: ui_node_model.cpp プロジェクト: Isaacssv552/ufoai
void uiModelNode::onCapturedMouseMove (uiNode_t* node, int x, int y)
{
	float* rotateAngles = EXTRADATA(node).angles;

	/* rotate a model */
	rotateAngles[YAW] -= ROTATE_SPEED * (x - oldMousePosX);
	rotateAngles[ROLL] += ROTATE_SPEED * (y - oldMousePosY);

	/* clamp the angles */
	rotateAngles[YAW] -= floor(rotateAngles[YAW] / 360.0) * 360.0;

	if (rotateAngles[ROLL] < 0.0)
		rotateAngles[ROLL] = 0.0;
	else if (rotateAngles[ROLL] > 180.0)
		rotateAngles[ROLL] = 180.0;

	oldMousePosX = x;
	oldMousePosY = y;
}
コード例 #16
0
/**
 * @brief Main function to draw a container node
 */
void uiBaseInventoryNode::draw (uiNode_t* node)
{
	const objDef_t* highlightType = nullptr;

	if (!EXTRADATA(node).super.container)
		return;
	if (!ui_inventory)
		return;
	/* is container invisible */
	if (node->color[3] < 0.001)
		return;

	/* Highlight weapons that the dragged ammo (if it is one) can be loaded into. */
	if (UI_DNDIsDragging() && UI_DNDGetType() == DND_ITEM) {
		highlightType = UI_DNDGetItem()->def();
	}

	UI_BaseInventoryNodeDraw2(node, highlightType);
}
コード例 #17
0
void uiSpinnerNode::draw (uiNode_t *node)
{
	vec2_t pos;
	const float delta = getDelta(node);
	const bool disabled = node->disabled || node->parent->disabled;

	UI_GetNodeAbsPos(node, pos);

	uiSpriteStatus_t status;
	uiSpriteStatus_t topStatus;
	uiSpriteStatus_t bottomStatus;

	if (disabled || delta == 0) {
		status = SPRITE_STATUS_DISABLED;
		topStatus = SPRITE_STATUS_DISABLED;
		bottomStatus = SPRITE_STATUS_DISABLED;
	} else {
		const float value = getValue(node);
		const float min = getMin(node);
		const float max = getMax(node);

		status = SPRITE_STATUS_NORMAL;

		bool increaseLocation = isPositionIncrease(node, mousePosX - pos[0], mousePosY - pos[1]);

		/* top button status */
		if (value >= max) {
			topStatus = SPRITE_STATUS_DISABLED;
		} else if (node->state && increaseLocation) {
			topStatus = SPRITE_STATUS_HOVER;
		} else {
			topStatus = SPRITE_STATUS_NORMAL;
		}
		/* bottom button status */
		if (value <= min) {
			bottomStatus = SPRITE_STATUS_DISABLED;
		} else if (node->state && !increaseLocation) {
			bottomStatus = SPRITE_STATUS_HOVER;
		} else {
			bottomStatus = SPRITE_STATUS_NORMAL;
		}
	}

	if (EXTRADATA(node).background)
		UI_DrawSpriteInBox(false, EXTRADATA(node).background, status, pos[0], pos[1], node->box.size[0], node->box.size[1]);
	if (EXTRADATA(node).topIcon)
		UI_DrawSpriteInBox(false, EXTRADATA(node).topIcon, topStatus, pos[0], pos[1], node->box.size[0], node->box.size[1]);
	if (EXTRADATA(node).bottomIcon)
		UI_DrawSpriteInBox(false, EXTRADATA(node).bottomIcon, bottomStatus, pos[0], pos[1], node->box.size[0], node->box.size[1]);
}
コード例 #18
0
/**
 * @brief Called when we press a key when the node got the focus
 * @return True, if we use the event
 */
bool uiTextEntryNode::onKeyPressed (uiNode_t* node, unsigned int key, unsigned short unicode)
{
	switch (key) {
	/* remove the last char. */
	case K_BACKSPACE:
		UI_TextEntryNodeEdit(node, K_BACKSPACE);
		return true;
	/* cancel the edition */
	case K_ESCAPE:
		isAborted = true;
		UI_RemoveFocus();
		return true;
	/* validate the edition */
	case K_ENTER:
	case K_KP_ENTER:
		UI_TextEntryNodeValidateEdition(node);
		UI_RemoveFocus();
		return true;
	case K_LEFTARROW:
	case K_KP_LEFTARROW:
		if (EXTRADATA(node).cursorPosition > 0)
			EXTRADATA(node).cursorPosition--;
		return true;
	case K_RIGHTARROW:
	case K_KP_RIGHTARROW:
		if (EXTRADATA(node).cursorPosition < UTF8_strlen(editedCvar->string))
			EXTRADATA(node).cursorPosition++;
		return true;
	case K_HOME:
	case K_KP_HOME:
		EXTRADATA(node).cursorPosition = 0;
		return true;
	case K_END:
	case K_KP_END:
		EXTRADATA(node).cursorPosition = UTF8_strlen(editedCvar->string);
		return true;
	case K_DEL:
	case K_KP_DEL:
		UI_TextEntryNodeEdit(node, K_DEL);
		return true;
	}

	/* non printable */
	if (unicode < 32 || (unicode >= 127 && unicode < 192))
		return false;

	/* add a char. */
	UI_TextEntryNodeEdit(node, unicode);
	return true;
}
コード例 #19
0
ファイル: ui_node_container.cpp プロジェクト: jklemmack/ufoai
/**
 * @brief Try to autoplace an item at a position
 * when right-click was used in the inventory.
 * @param[in] node The context node
 * @param[in] mouseX X mouse coordinates.
 * @param[in] mouseY Y mouse coordinates.
 */
static void UI_ContainerNodeAutoPlace (uiNode_t* node, int mouseX, int mouseY)
{
	if (!ui_inventory)
		return;

	/* don't allow this in tactical missions */
	if (CL_BattlescapeRunning())
		return;

	const int sel = cl_selected->integer;
	if (sel < 0)
		return;

	assert(EXTRADATA(node).container);

	invList_t *ic = UI_ContainerNodeGetItemAtPosition(node, mouseX, mouseY);
	if (!ic)
		return;
	UI_ContainerNodeAutoPlaceItem(node, ic);
}
コード例 #20
0
ファイル: ui_node_image.cpp プロジェクト: AresAndy/ufoai
/**
 * @brief Handled after the end of the load of the node from the script (all data and/or child are set)
 */
void uiImageNode::onLoaded (uiNode_t* node)
{
	/* update the size when its possible */
	if (Vector2Empty(node->box.size)) {
		if (EXTRADATA(node).texl[0] != 0 || EXTRADATA(node).texh[0]) {
			node->box.size[0] = EXTRADATA(node).texh[0] - EXTRADATA(node).texl[0];
			node->box.size[1] = EXTRADATA(node).texh[1] - EXTRADATA(node).texl[1];
		} else if (EXTRADATA(node).source) {
			const image_t* image = UI_LoadImage(EXTRADATA(node).source);
			if (image) {
				node->box.size[0] = image->width;
				node->box.size[1] = image->height;
			}
		}
	}
#ifdef DEBUG
	if (Vector2Empty(node->box.size)) {
		if (node->onClick || node->onRightClick || node->onMouseEnter || node->onMouseLeave || node->onWheelUp || node->onWheelDown || node->onWheel || node->onMiddleClick) {
			Com_DPrintf(DEBUG_CLIENT, "Node '%s' is an active image without size\n", UI_GetPath(node));
		}
	}
#endif
}
コード例 #21
0
ファイル: ui_node_model.c プロジェクト: kevlund/ufoai
static void UI_ModelNodeCapturedMouseMove (uiNode_t *node, int x, int y)
{
	float *rotateAngles = EXTRADATA(node).angles;

	/* rotate a model */
	rotateAngles[YAW] -= ROTATE_SPEED * (x - oldMousePosX);
	rotateAngles[ROLL] += ROTATE_SPEED * (y - oldMousePosY);

	/* clamp the angles */
	while (rotateAngles[YAW] > 360.0)
		rotateAngles[YAW] -= 360.0;
	while (rotateAngles[YAW] < 0.0)
		rotateAngles[YAW] += 360.0;

	if (rotateAngles[ROLL] < 0.0)
		rotateAngles[ROLL] = 0.0;
	else if (rotateAngles[ROLL] > 180.0)
		rotateAngles[ROLL] = 180.0;

	oldMousePosX = x;
	oldMousePosY = y;
}
コード例 #22
0
ファイル: ui_node_container.cpp プロジェクト: jklemmack/ufoai
/**
 * @brief Draws the free and usable inventory positions when dragging an item.
 * @note Only call this function in dragging mode
 */
static void UI_ContainerNodeDrawFreeSpace (uiNode_t *node, inventory_t *inv)
{
	const objDef_t *od = UI_DNDGetItem()->item;	/**< Get the 'type' of the dragged item. */
	vec2_t nodepos;

	/* Draw only in dragging-mode and not for the equip-floor */
	assert(UI_DNDIsDragging());
	assert(inv);

	UI_GetNodeAbsPos(node, nodepos);
	/* if single container (hands, extension, headgear) */
	if (EXTRADATA(node).container->single) {
		/* if container is free or the dragged-item is in it */
		if (UI_DNDIsSourceNode(node) || INVSH_CheckToInventory(inv, od, EXTRADATA(node).container, 0, 0, dragInfoIC))
			UI_DrawFree(EXTRADATA(node).container->id, node, nodepos[0], nodepos[1], node->box.size[0], node->box.size[1], true);
	} else {
		/* The shape of the free positions. */
		uint32_t free[SHAPE_BIG_MAX_HEIGHT];
		bool showTUs = true;
		int x, y;

		OBJZERO(free);

		for (y = 0; y < SHAPE_BIG_MAX_HEIGHT; y++) {
			for (x = 0; x < SHAPE_BIG_MAX_WIDTH; x++) {
				/* Check if the current position is usable (topleft of the item). */

				/* Add '1's to each position the item is 'blocking'. */
				const int checkedTo = INVSH_CheckToInventory(inv, od, EXTRADATA(node).container, x, y, dragInfoIC);
				if (checkedTo & INV_FITS)				/* Item can be placed normally. */
					INVSH_MergeShapes(free, (uint32_t)od->shape, x, y);
				if (checkedTo & INV_FITS_ONLY_ROTATED)	/* Item can be placed rotated. */
					INVSH_MergeShapes(free, INVSH_ShapeRotate((uint32_t)od->shape), x, y);

				/* Only draw on existing positions. */
				if (INVSH_CheckShape(EXTRADATA(node).container->shape, x, y)) {
					if (INVSH_CheckShape(free, x, y)) {
						UI_DrawFree(EXTRADATA(node).container->id, node, nodepos[0] + x * C_UNIT, nodepos[1] + y * C_UNIT, C_UNIT, C_UNIT, showTUs);
						showTUs = false;
					}
				}
			}
		}
	}
}
コード例 #23
0
ファイル: ui_node_container.cpp プロジェクト: jklemmack/ufoai
/**
 * @brief Calculates the size of a container node and links the container
 * into the node (uses the @c invDef_t shape bitmask to determine the size)
 * @param[in,out] node The node to get the size for
 */
void uiContainerNode::onLoaded (uiNode_t* const node)
{
	const char *name;
	const invDef_t *container;

	/** @todo find a better way to add more equip node, without this hack */
	name = node->name;
	if (Q_strstart(node->name, "equip_"))
		name = "equip";

	container = INVSH_GetInventoryDefinitionByID(name);
	if (container == NULL)
		return;

	EXTRADATA(node).container = container;

	if (UI_IsScrollContainerNode(node)) {
		/* No need to compute the size, the script provide it */
	} else {
		int i, j;
		/* Start on the last bit of the shape mask. */
		for (i = SHAPE_BIG_MAX_WIDTH - 1; i >= 0; i--) {
			for (j = 0; j < SHAPE_BIG_MAX_HEIGHT; j++)
				if (container->shape[j] & (1 << i))
					break;
			if (j < SHAPE_BIG_MAX_HEIGHT)
				break;
		}
		node->box.size[0] = C_UNIT * (i + 1) + 0.01;

		/* start on the lower row of the shape mask */
		for (i = SHAPE_BIG_MAX_HEIGHT - 1; i >= 0; i--)
			if (container->shape[i] & ~0x0)
				break;
		node->box.size[1] = C_UNIT * (i + 1) + 0.01;
	}
}
コード例 #24
0
ファイル: ui_node_optionlist.cpp プロジェクト: drone-pl/ufoai
/**
 * @brief Update the scroll according to the number
 * of items and the size of the node
 */
static void UI_OptionListNodeUpdateScroll (uiNode_t* node)
{
	int lineHeight;
	bool updated;
	int elements;

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

	elements = (node->box.size[1] - node->padding - node->padding) / lineHeight;
	updated = EXTRADATA(node).scrollY.set(-1, elements, EXTRADATA(node).count);
	if (updated) {
		if (EXTRADATA(node).onViewChange) {
			UI_ExecuteEventActions(node, EXTRADATA(node).onViewChange);
		}
		else if (EXTRADATA(node).lua_onViewChange != LUA_NOREF) {
			UI_ExecuteLuaEventScript (node, EXTRADATA(node).lua_onViewChange);
		}
	}
}
コード例 #25
0
/**
 * @brief Return the first option of the node
 * @todo check versionId and update cached data, and fire events
 */
uiNode_t* UI_AbstractOptionGetFirstOption (uiNode_t * node)
{
	if (node->firstChild && node->firstChild->behaviour == ui_optionBehaviour) {
		return node->firstChild;
	} else {
		const int v = UI_GetDataVersion(EXTRADATA(node).dataId);
		if (v != EXTRADATA(node).versionId) {
			int count = 0;
			uiNode_t *option = UI_GetOption(EXTRADATA(node).dataId);
			while (option) {
				if (!option->invis)
					count++;
				option = option->next;
			}
			EXTRADATA(node).count = count;
			EXTRADATA(node).versionId = v;
		}
		return UI_GetOption(EXTRADATA(node).dataId);
	}
}
コード例 #26
0
ファイル: ui_node_text.cpp プロジェクト: XenderPL/ufoai
/**
 * @brief Scroll to the bottom
 * @param[in] nodePath absolute path
 */
void UI_TextScrollEnd (const char* nodePath)
{
	uiNode_t* node = UI_GetNodeByPath(nodePath);
	if (!node) {
		Com_DPrintf(DEBUG_CLIENT, "UI_TextScrollEnd: Node '%s' could not be found\n", nodePath);
		return;
	}

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

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

	if (EXTRADATA(node).super.scrollY.fullSize > EXTRADATA(node).super.scrollY.viewSize) {
		EXTRADATA(node).super.scrollY.viewPos = EXTRADATA(node).super.scrollY.fullSize - EXTRADATA(node).super.scrollY.viewSize;
		UI_ExecuteEventActions(node, EXTRADATA(node).super.onViewChange);
	}
}
コード例 #27
0
ファイル: ui_node_vscrollbar.cpp プロジェクト: AresAndy/ufoai
/**
 * @brief Set the position of the scrollbar to a value
 */
static void UI_VScrollbarNodeSet (uiNode_t* node, int value)
{
	int pos = value;

	if (pos < 0) {
		pos = 0;
	} else if (pos > EXTRADATA(node).fullsize - EXTRADATA(node).viewsize) {
		pos = EXTRADATA(node).fullsize - EXTRADATA(node).viewsize;
	}
	if (pos < 0)
		pos = 0;

	/* nothing change */
	if (EXTRADATA(node).pos == pos)
		return;

	/* update status */
	EXTRADATA(node).pos = pos;

	/* fire change event */
	if (node->onChange) {
		UI_ExecuteEventActions(node, node->onChange);
	}
}
コード例 #28
0
static void UI_PanelNodeDoLayout (uiNode_t *node)
{
	if (!node->invalidated)
		return;

	switch (EXTRADATA(node).layout) {
	case LAYOUT_NONE:
		break;
	case LAYOUT_TOP_DOWN_FLOW:
		UI_TopDownFlowLayout(node, EXTRADATA(node).layoutMargin);
		break;
	case LAYOUT_LEFT_RIGHT_FLOW:
		UI_LeftRightFlowLayout(node, EXTRADATA(node).layoutMargin);
		break;
	case LAYOUT_BORDER:
		UI_BorderLayout(node, EXTRADATA(node).layoutMargin);
		break;
	case LAYOUT_PACK:
		UI_PackLayout(node, EXTRADATA(node).layoutMargin);
		break;
	case LAYOUT_STAR:
		UI_StarLayout(node);
		break;
	case LAYOUT_CLIENT:
		UI_ClientLayout(node);
		break;
	case LAYOUT_COLUMN:
		UI_ColumnLayout(node);
		break;
	default:
		Com_Printf("UI_PanelNodeDoLayout: layout '%d' unsupported.", EXTRADATA(node).layout);
		break;
	}

	localBehaviour->super->doLayout(node);
}
コード例 #29
0
void uiSequenceNode::onLeftClick (uiNode_t *node, int x, int y)
{
	if (EXTRADATA(node).context != NULL) {
		SEQ_SendClickEvent(EXTRADATA(node).context);
	}
}
コード例 #30
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);
}