Files
PHY/Source/PHYInventory/Public/UI/ItemStacks/ItemStackContainer.h
2026-03-03 01:23:02 +08:00

147 lines
5.7 KiB
C++

//
#pragma once
#include "CoreMinimal.h"
#include "CommonUserWidget.h"
#include "GIS_InventoryMeesages.h"
#include "GIS_ItemInfo.h"
#include "ItemData.h"
#include "UI/Common/GUIS_UserWidgetInterface.h"
#include "ItemStackContainer.generated.h"
class UCommonTabListWidgetBase;
class UGIS_AsyncAction_WaitInventorySystem;
class UListView;
class IItemFilterInterface;
/**
*
*/
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FItemSelectionOrHoveredChanged,UItemData*,SelectedItemData,bool,bSelected);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FItemClickedEvent,UItemData*,ClickedItemData);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FItemEntryGeneratedEvent,UUserWidget*,Widget);
UCLASS()
class PHYINVENTORY_API UItemStackContainer : public UCommonUserWidget,public IGUIS_UserWidgetInterface
{
GENERATED_BODY()
protected:
//~ Begin IGUIS_UserWidgetInterface Interface
virtual void SetOwningActor_Implementation(AActor* NewOwningActor) override;
virtual void OnDeactivated_Implementation() override;
virtual void OnActivated_Implementation() override;
virtual AActor* GetOwningActor_Implementation() override;
//~ End IGUIS_UserWidgetInterface Interface
public:
// 添加过滤器对象
void AddFilterObject(UObject* InFilterObject);
// 移除过滤器对象
void RemoveFilterObject(UObject* InFilterObject);
UPROPERTY(BlueprintAssignable)
FItemSelectionOrHoveredChanged OnItemSelectionChanged;
UPROPERTY(BlueprintAssignable)
FItemSelectionOrHoveredChanged OnItemHoveredChanged;
UPROPERTY(BlueprintAssignable)
FItemClickedEvent OnItemClicked;
UPROPERTY(BlueprintAssignable)
FItemEntryGeneratedEvent OnItemEntryGenerated;
UPROPERTY(BlueprintAssignable)
FItemClickedEvent OnItemDoubleClicked;
UPROPERTY()
UGIS_AsyncAction_WaitInventorySystem* WaitInventorySystem;
void SetSelectedIndexForNewItem(const int32 NewSelectedIndex);
// 交换两个item data槽位
bool SwapItemDataSlots(const int32 IndexA,const int32 IndexB);
bool SwapItemDataToOtherContainer(const int32 SourceIndex,UItemStackContainer* TargetContainer,const int32 TargetIndex);
// 检查是否可以移动item
virtual bool CanMoveItem(const int32 IndexA,UItemStackContainer* TargetContainer,const int32 IndexB);
// 是否允许拖拽操作
UFUNCTION(BlueprintImplementableEvent,BlueprintPure,BlueprintCallable)
bool IsDraggingAllowed() const;
FORCEINLINE bool IsItemActionAllowed() const { return bAllowItemAction; }
int32 FindItemSlotIndex(const UItemData* InItemData) const;
FORCEINLINE TArray<TObjectPtr<UItemData>> GetItemDataArray() const { return ItemDataArray; }
// 同步item data数组到listview
void SyncItemDataToListView();
// 用来拖拽操作时记录上一次放下的item index
int32 LastDropIndex = INDEX_NONE;
private:
TWeakObjectPtr<AActor> OwningActor;
TWeakObjectPtr<UGIS_InventorySystemComponent> InventorySystemComponent;
// 配置
UPROPERTY(EditAnywhere,Category="Config|ItemStackContainer")
FGameplayTag CollectionToTrackTag;
// Item所有tag过滤器映射表,可以通过name来过滤Item,用于tab切换等功能
UPROPERTY(EditAnywhere,Category="Config|Filter")
TMap<FName,FGameplayTagQuery> ItemFilterMap;
// 要过滤的Item名称
UPROPERTY(EditAnywhere,Category="Config|Filter")
FName ItemFilterName;
UPROPERTY(EditAnywhere,Category="Config")
bool bAllowItemAction = true;
UPROPERTY(EditAnywhere,Category="Config")
bool bCreateDefaultItemDataSlots = true;
UPROPERTY(EditAnywhere,Category="Config",meta=(EditCondition="bCreateDefaultItemDataSlots"))
int32 DefaultItemDataSlotCount = 20;
UPROPERTY()
TArray<UObject*> ItemFilterObjects;
// 容器用来展示item的listview
UPROPERTY(BlueprintReadOnly,meta=(AllowPrivateAccess="true"))
TObjectPtr<UListView> ItemListView;
UPROPERTY()
TObjectPtr<UCommonTabListWidgetBase> FilterTabsReference;
// 当前容器中关联的item数据
UPROPERTY()
TArray<TObjectPtr<UItemData>> ItemDataArray;
// The item stack data
// 给指定槽位的ItemData赋值
void AssignItemInfoToItemData(const FGIS_ItemInfo& InInfo,const int32 SlotIndex);
void UnassignItemInfoToItemData(const FGIS_ItemInfo& InInfo);
int32 FindItemIndexFromDataByStackID(const FGuid& StackID) const;
// 从库存系统获取数据
TArray<FGIS_ItemInfo> GetItemInfoArrayFromInventorySystem();
// 重置item data数组
void ResetItemDataArray();
// 设置或添加item info到item data数组
void SetOrAddItemInfoToItemDataArray(const FGIS_ItemInfo& InInfo,const int32 SlotIndex);
// 同步item infos到item data数组
void SyncItemInfoToItemDataArray(const TArray<FGIS_ItemInfo>& InItemInfos);
// 为新物品查找合适的item data槽位
int32 FindSuitableItemDataSlotForNewItem();
// 聚合函数,同步所有数据
void SyncAll();
public:
// 必须配置filter map才能使用
void ApplyFilter(const FName& InFilterName);
private:
void HandleItemSelectionChanged(UObject* Object) const;
void HandleItemHoveredChanged(UObject* Object, bool bIsHovered) const;
void HandleItemClicked(UObject* Object) const;
void HandleListViewEntryWidgetGenerated(UUserWidget& UserWidget) const;
void HandleItemDoubleClicked(UObject* Object) const;
void RegisterListViewEvents();
void UnregisterListViewEvents() const;
FDelegateHandle ItemSelectionChangedHandle;
FDelegateHandle ItemHoveredChangedHandle;
FDelegateHandle ItemClickedHandle;
FDelegateHandle ListViewEntryWidgetGeneratedHandle;
FDelegateHandle ItemDoubleClickedHandle;
int32 SelectedIndexForNewItem = INDEX_NONE;
// 处理库存系统的item堆栈变化消息
UFUNCTION()
void HandleInventoryStackChanged(const FGIS_InventoryStackUpdateMessage& Message);
UFUNCTION()
void HandleTabSelected(FName TabId);
UFUNCTION()
void HandleInventorySystemInitialized();
// 创建默认的item data槽位
void CreateDefaultItemDataSlots();
};