/**
 * @brief Main function to draw a container node
 */
void uiContainerNode::draw (uiNode_t *node)
{
	const objDef_t *highlightType = NULL;

	if (!EXTRADATA(node).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()->item;
	}

	if (EXTRADATA(node).container->single) {
		UI_ContainerNodeDrawSingle(node, highlightType);
	} else {
		if (UI_IsScrollContainerNode(node)) {
			assert(false);
		} else {
			UI_ContainerNodeDrawGrid(node, highlightType);
		}
	}

	/* Draw free space if dragging - but not for idEquip */
	if (UI_DNDIsDragging() && EXTRADATA(node).container->id != csi.idEquip)
		UI_ContainerNodeDrawFreeSpace(node, ui_inventory);

	if (UI_DNDIsTargetNode(node))
		UI_ContainerNodeDrawDropPreview(node);
}
Exemple #2
0
/**
 * @brief Called by the client when the user type a key
 * @param[in] key key code, either K_ value or lowercase ascii
 * @param[in] unicode translated meaning of keypress in unicode
 * @return true, if we used the event
 * @todo think about what we should do when the mouse is captured
 */
bool UI_KeyPressed (unsigned int key, unsigned short unicode)
{
	int windowId;
	int lastWindowId;

	if (UI_DNDIsDragging()) {
		if (key == K_ESCAPE)
			UI_DNDAbort();
		return false;
	}

	if (key == K_ESCAPE && CL_BattlescapeRunning()
	 && selActor && CL_ActorFireModeActivated(selActor->actorMode)) {
		/* Cancel firing with Escape, needed for Android, where right mouse click is bound to multitouch, which is non-obvious */
		CL_ActorSetMode(selActor, M_MOVE);
		return true;
	}

	/* translate event into the node with focus */
	if (focusNode && UI_Node_KeyPressed(focusNode, key, unicode)) {
		return true;
	}

	/* else use common behaviour */
	switch (key) {
	case K_TAB:
		if (UI_FocusNextActionNode())
			return true;
		break;
	case K_ENTER:
	case K_KP_ENTER:
		if (UI_FocusExecuteActionNode())
			return true;
		break;
	case K_ESCAPE:
		if (UI_GetMouseCapture() != nullptr) {
			UI_MouseRelease();
			return true;
		}
		UI_PopWindowWithEscKey();
		return true;
	}

	lastWindowId = UI_GetLastFullScreenWindow();
	if (lastWindowId < 0)
		return false;

	/* check "active" window from top to down */
	for (windowId = ui_global.windowStackPos - 1; windowId >= lastWindowId; windowId--) {
		const uiNode_t* window = ui_global.windowStack[windowId];
		if (!window)
			return false;
		if (UI_KeyPressedInWindow(key, window))
			return true;
		if (UI_WindowIsModal(window))
			break;
	}

	return false;
}
Exemple #3
0
/**
 * @brief Start to drag an item
 * @sa UI_DNDDrag
 * @sa UI_DNDDrop
 * @sa UI_DNDAbort
 */
void UI_DNDDragItem (uiNode_t* node, const Item* item)
{
	UI_DNDDrag(node);
	assert(UI_DNDIsDragging());
	objectType = DND_ITEM;
	draggingItem = *item;
}
void uiContainerNode::onMouseDown (uiNode_t *node, int x, int y, int button)
{
	switch (button) {
	case K_MOUSE1:
	{
		/* start drag and drop */
		int fromX, fromY;
		dragInfoIC = UI_ContainerNodeGetItemAtPosition(node, x, y, &fromX, &fromY);
		if (dragInfoIC) {
			dragInfoFromX = fromX;
			dragInfoFromY = fromY;
			oldMouseX = x;
			oldMouseY = y;
			UI_SetMouseCapture(node);
			EXTRADATA(node).lastSelectedId = dragInfoIC->item.item->idx;
			if (EXTRADATA(node).onSelect) {
				UI_ExecuteEventActions(node, EXTRADATA(node).onSelect);
			}
		}
		break;
	}
	case K_MOUSE2:
		if (UI_DNDIsDragging()) {
			UI_DNDAbort();
		} else {
			/* auto place */
			UI_ContainerNodeAutoPlace(node, x, y);
		}
		break;
	default:
		break;
	}
}
Exemple #5
0
/**
 * @brief Release all captured input (keyboard or mouse)
 */
void UI_ReleaseInput (void)
{
	UI_RemoveFocus();
	UI_MouseRelease();
	if (UI_DNDIsDragging())
		UI_DNDAbort();
}
Exemple #6
0
/**
 * @brief Private function to initialize a the start of a DND
 * @sa UI_DNDDragItem
 * @sa UI_DNDDrop
 * @sa UI_DNDAbort
 */
static void UI_DNDDrag (uiNode_t* node)
{
	assert(!UI_DNDIsDragging());
	objectType = DND_SOMETHING;
	sourceNode = node;

	UI_PlaySound("item-drag");
}
void uiBaseInventoryNode::onMouseUp (uiNode_t* node, int x, int y, int button)
{
	if (button != K_MOUSE1)
		return;
	if (UI_GetMouseCapture() == node) {
		UI_MouseRelease();
	}
	if (UI_DNDIsDragging()) {
		UI_DNDDrop();
	}
}
Exemple #8
0
/**
 * @brief Called by the client when the user type a key
 * @param[in] key key code, either K_ value or lowercase ascii
 * @param[in] unicode translated meaning of keypress in unicode
 * @return true, if we used the event
 * @todo think about what we should do when the mouse is captured
 */
bool UI_KeyPressed (unsigned int key, unsigned short unicode)
{
	int windowId;
	int lastWindowId;

	if (UI_DNDIsDragging()) {
		if (key == K_ESCAPE)
			UI_DNDAbort();
		return false;
	}

	/* translate event into the node with focus */
	if (focusNode && UI_Node_KeyPressed(focusNode, key, unicode)) {
		return true;
	}

	/* else use common behaviour */
	switch (key) {
	case K_TAB:
		if (UI_FocusNextActionNode())
			return true;
		break;
	case K_ENTER:
	case K_KP_ENTER:
		if (UI_FocusExecuteActionNode())
			return true;
		break;
	case K_ESCAPE:
		if (UI_GetMouseCapture() != NULL) {
			UI_MouseRelease();
			return true;
		}
		UI_PopWindowWithEscKey();
		return true;
	}

	lastWindowId = UI_GetLastFullScreenWindow();
	if (lastWindowId < 0)
		return false;

	/* check "active" window from top to down */
	for (windowId = ui_global.windowStackPos - 1; windowId >= lastWindowId; windowId--) {
		const uiNode_t *window = ui_global.windowStack[windowId];
		if (!window)
			return false;
		if (UI_KeyPressedInWindow(key, window))
			return true;
		if (UI_WindowIsModal(window))
			break;
	}

	return false;
}
Exemple #9
0
/**
 * @brief Drop the object at the current position
 * @sa UI_DNDStartDrag
 * @sa UI_DNDDrop
 */
void UI_DNDAbort (void)
{
	assert(UI_DNDIsDragging());
	assert(objectType != DND_NOTHING);
	assert(sourceNode != nullptr);

	if (nodeAcceptDND && targetNode) {
		UI_Node_DndLeave(targetNode);
	}
	UI_Node_DndFinished(sourceNode, false);

	UI_DNDCleanup();
	UI_InvalidateMouse();
}
Exemple #10
0
/**
 * @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;
					}
				}
			}
		}
	}
}
/**
 * @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);
}
Exemple #12
0
/**
 * @brief Drop the object at the current position
 * @sa UI_DNDStartDrag
 * @sa UI_DNDAbort
 */
void UI_DNDDrop (void)
{
	bool result = false;
	assert(UI_DNDIsDragging());
	assert(objectType != DND_NOTHING);
	assert(sourceNode != nullptr);

	if (!positionAcceptDND) {
		UI_DNDAbort();
		return;
	}

	if (targetNode) {
		result = UI_Node_DndDrop(targetNode, mousePosX, mousePosY);
	}
	UI_Node_DndFinished(sourceNode, result);

	UI_PlaySound("item-drop");

	UI_DNDCleanup();
	UI_InvalidateMouse();
}
/**
 * @brief Draws the 3D-cursor in battlemode and the icons/info next to it.
 */
static void SCR_DrawCursor (void)
{
	if (scr_showcursor->integer == 0)
		return;

	if (!scr_cursor->integer)
		return;

	if (scr_cursor->modified) {
		scr_cursor->modified = qfalse;
		SCR_TouchPics();
	}

	if (!cursorImage[0])
		return;

	if (!UI_DNDIsDragging()) {
		const char *pic;
		image_t *image;

		if (cls.team != cl.actTeam && CL_BattlescapeRunning())
			pic = "pics/cursors/wait";
		else
			pic = cursorImage;

		image = R_FindImage(pic, it_pic);
		if (image)
			R_DrawImage(mousePosX - image->width / 2, mousePosY - image->height / 2, image);

		if (IN_GetMouseSpace() == MS_WORLD && CL_BattlescapeRunning()) {
			HUD_UpdateCursor();
		}
	} else {
		UI_DrawCursor();
	}
}
Exemple #14
0
/**
 * @brief Return source of the DND
 */
uiNode_t* UI_DNDGetSourceNode (void)
{
	assert(UI_DNDIsDragging());
	return sourceNode;
}
Exemple #15
0
/**
 * @brief Return target of the DND
 */
uiNode_t* UI_DNDGetTargetNode (void)
{
	assert(UI_DNDIsDragging());
	return targetNode;
}
Exemple #16
0
/**
 * @brief Return true if the requested node is the source of the DND
 */
bool UI_DNDIsSourceNode (uiNode_t* node)
{
	if (!UI_DNDIsDragging())
		return false;
	return sourceNode == node;
}
Exemple #17
0
/**
 * @brief Return true if the requested node is the current target of the DND
 */
bool UI_DNDIsTargetNode (uiNode_t* node)
{
	if (!UI_DNDIsDragging())
		return false;
	return targetNode == node;
}
Exemple #18
0
/**
 * @brief Is called every time the mouse position change
 */
void UI_MouseMove (int x, int y)
{
	if (UI_DNDIsDragging())
		return;

	if (pressedNode && !capturedNode) {
		if (pressedNodeLocationX != UI_STARTDRAG_ALREADY_SENT) {
			UI_TimerStop(longPressTimer);
			int dist = abs(pressedNodeLocationX - x) + abs(pressedNodeLocationY - y);
			if (dist > 4) {
				uiNode_t* node = pressedNode;
				while (node) {
					if (UI_Node_StartDragging(node, pressedNodeLocationX, pressedNodeLocationY, x, y, pressedNodeButton))
						break;
					node = node->parent;
				}
				pressedNodeLocationX = UI_STARTDRAG_ALREADY_SENT;
			}
		}
	}

	/* send the captured move mouse event */
	if (capturedNode) {
		UI_Node_CapturedMouseMove(capturedNode, x, y);
		return;
	}

	hoveredNode = UI_GetNodeAtPosition(x, y);

	/* update houvered node by sending messages */
	if (oldHoveredNode != hoveredNode) {
		uiNode_t* commonNode = hoveredNode;
		uiNode_t* node;

		/* search the common node */
		while (commonNode) {
			node = oldHoveredNode;
			while (node) {
				if (node == commonNode)
					break;
				node = node->parent;
			}
			if (node != nullptr)
				break;
			commonNode = commonNode->parent;
		}

		/* send 'leave' event from old node to common node */
		node = oldHoveredNode;
		while (node != commonNode) {
			UI_Node_MouseLeave(node);
			node = node->parent;
		}
		if (oldHoveredNode)
			oldHoveredNode->state = false;

		/* send 'enter' event from common node to new node */
		while (commonNode != hoveredNode) {
			/** @todo we can remove that loop with an array allocation */
			node = hoveredNode;
			while (node->parent != commonNode)
				node = node->parent;
			commonNode = node;
			UI_Node_MouseEnter(node);
		}
		if (hoveredNode) {
			hoveredNode->state = true;
			UI_Node_MouseEnter(node);
		}
	}

	oldHoveredNode = hoveredNode;

	/* send the move event */
	if (hoveredNode)
		UI_Node_MouseMove(hoveredNode, x, y);
}