// #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> GetItemDataArray() const { return ItemDataArray; } // 同步item data数组到listview void SyncItemDataToListView(); // 用来拖拽操作时记录上一次放下的item index int32 LastDropIndex = INDEX_NONE; private: TWeakObjectPtr OwningActor; TWeakObjectPtr InventorySystemComponent; // 配置 UPROPERTY(EditAnywhere,Category="Config|ItemStackContainer") FGameplayTag CollectionToTrackTag; // Item所有tag过滤器映射表,可以通过name来过滤Item,用于tab切换等功能 UPROPERTY(EditAnywhere,Category="Config|Filter") TMap 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 ItemFilterObjects; // 容器用来展示item的listview UPROPERTY(BlueprintReadOnly,meta=(AllowPrivateAccess="true")) TObjectPtr ItemListView; UPROPERTY() TObjectPtr FilterTabsReference; // 当前容器中关联的item数据 UPROPERTY() TArray> 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 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& 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(); };