Trying to get popup menu to handle use item event

Godot Version

Godot 4.2

Question

So I’ve got a basic modular inventory set up. I can swap items, use items on right click, and drop items.

Recently, I setup a popup menu to allow the player to select between Use, Help, and Drop, just to keep things more organized and straightforward. My issue is trying to get the item to be used through the used button from the popup. I don’t know where to handle that event.

If anyone could help me in structuring this properly with signals, I would be really grateful.

Here is my code for the popup menu:

extends Control

var last_mouse_pos: Vector2
@onready var popup_menu = $PopupMenu

signal use_item_from_popup(_inventory_data: InventoryData, _index: int)
signal help_item_from_popup(_inventory_data: InventoryData, _index: int)
signal drop_item_from_popup(_inventory_data: InventoryData, _index: int)


enum popup_ID{
	Use,
	Help,
	Drop
}


func _ready():
	popup_menu.add_item("Use", popup_ID.Use)
	popup_menu.add_item("Help", popup_ID.Help)
	popup_menu.add_item("Drop", popup_ID.Drop)

func _input(event):
	if event is InputEventMouseButton \
	and event.is_pressed() and event.button_index == MOUSE_BUTTON_RIGHT\
	and Global.player.locked:
		last_mouse_pos = get_global_mouse_position()
		popup_menu.popup(Rect2(last_mouse_pos.x, last_mouse_pos.y, popup_menu.size.x, popup_menu.size.y))


func _on_popup_menu_id_pressed(id):
	if id == popup_ID.Use:
#the use item should be handled here.
		pass

func _on_popup_menu_mouse_exited():
	popup_menu.visible = false
	

and here is my main inventory code:

extends Control
@onready var player_inventory = $PlayerInventory
@onready var grabbed_slot = $GrabbedSlot
@onready var external_inventory = $ExternalInventory
@onready var primary_weapon = $"Equipable Items/PrimaryWeapon"
@onready var secondary_weapon = $"Equipable Items/SecondaryWeapon"
@onready var wearable = $"Equipable Items/Wearable"
@onready var melee_explosive = $"Equipable Items/Melee + Explosive"
@onready var inventory_popup = $"Inventory Popup"

var grabbed_slot_data: SlotData
var external_inventory_owner

signal drop_slot_data(slot_data: SlotData)

func _physics_process(delta):
	if grabbed_slot.visible:
		grabbed_slot.global_position = get_global_mouse_position() + Vector2(5, 5)

func set_player_inventory_data(inventory_data: InventoryData) -> void:
	inventory_data.inventory_interact.connect(on_inventory_interact)
	player_inventory.set_inventory_data(inventory_data)

func set_primary_weapon_data(inventory_data: InventoryData) -> void:
	inventory_data.inventory_interact.connect(on_inventory_interact)
	primary_weapon.set_inventory_data(inventory_data)

func set_secondary_weapon_data(inventory_data: InventoryData) -> void:
	inventory_data.inventory_interact.connect(on_inventory_interact)
	secondary_weapon.set_inventory_data(inventory_data)

func set_wearable_item_data(inventory_data: InventoryData) -> void:
	inventory_data.inventory_interact.connect(on_inventory_interact)
	wearable.set_inventory_data(inventory_data)
	
func set_melee_explosive_data(inventory_data: InventoryData) -> void:
	inventory_data.inventory_interact.connect(on_inventory_interact)
	melee_explosive.set_inventory_data(inventory_data)

func set_external_inventory(_external_inventory_owner) -> void:
	external_inventory_owner = _external_inventory_owner
	var inventory_data = external_inventory_owner.inventoryData
	
	inventory_data.inventory_interact.connect(on_inventory_interact)
	external_inventory.set_inventory_data(inventory_data)
	
	external_inventory.show()
	
func clear_external_inventory() -> void:
	if external_inventory_owner:
		var inventory_data = external_inventory_owner.inventoryData
		inventory_data.inventory_interact.disconnect(on_inventory_interact)
		external_inventory.clear_inventory_data(inventory_data)
		
		external_inventory.hide()
		external_inventory_owner = null

func on_inventory_interact(inventory_data: InventoryData, index: int, button: int):
	match [grabbed_slot_data, button]:
		[null, MOUSE_BUTTON_LEFT]:
			grabbed_slot_data = inventory_data.grab_slot_data(index)
		[_, MOUSE_BUTTON_LEFT]:
			grabbed_slot_data = inventory_data.drop_slot_data(grabbed_slot_data, index)
		[null, MOUSE_BUTTON_RIGHT]:
			inventory_popup.visible
			inventory_data.use_slot_data(index)
		[_, MOUSE_BUTTON_RIGHT]:
			grabbed_slot_data = inventory_data.drop_single_slot_data(grabbed_slot_data, index)

	update_grabbed_slot()


func update_grabbed_slot() -> void:
	if grabbed_slot_data:
		grabbed_slot.show()
		grabbed_slot.set_slot_data(grabbed_slot_data)
	else:
		grabbed_slot.hide()


func _on_gui_input(event):
	if event is InputEventMouseButton and event.is_pressed() and grabbed_slot_data:
		match event.button_index:
			MOUSE_BUTTON_LEFT:
				drop_slot_data.emit(grabbed_slot_data)
				grabbed_slot_data = null
			MOUSE_BUTTON_RIGHT:
				drop_slot_data.emit(grabbed_slot_data.create_single_slot())
				if grabbed_slot_data.quantity < 1:
					grabbed_slot_data = null
				
		update_grabbed_slot()

func _on_visibility_changed():
	if !visible and grabbed_slot_data:
		drop_slot_data.emit(grabbed_slot_data)
		grabbed_slot_data = null
		update_grabbed_slot()


func _on_inventory_popup_use_item_from_popup(_inventory_data, _index):
	pass # 

Here is the slot data functions for reference.

func on_slot_clicked(index: int, button: int):
	inventory_interact.emit(self, index, button)
	
func use_slot_data(index: int) -> void:
	var slot_data = slotDatas[index]
	
	if !slot_data:
		return
	if slot_data.itemData is UsableItem:
		slot_data.quantity -= 1
		if slot_data.quantity < 1:
			slotDatas[index] = null
		
	print(slot_data.itemData.name)
	PlayerManager.use_item(slot_data)
	inventory_updated.emit(self)

Basically, I’m trying to get this function into the popup code. Specifically, I’m trying to pass the inventory data from the main code and into the popup code. I don’t have a great idea of how signals work and I feel like they would be of use in this case. I don’t want to create additional variables to store the inventory data info, to keep things clean. Any help is greatly appreciated.

Thanks!