// Fill out your copyright notice in the Description page of Project Settings. #include "Widgets/BagConfigEditorWidget.h" #include "PropertyCustomizationHelpers.h" #include "Framework/Notifications/NotificationManager.h" #include "ProjectFish/DataAsset/BagShapeAsset.h" #include "Widgets/Notifications/SNotificationList.h" void SBagConfigEditorWidget::Construct(const FArguments& InArgs) { BagConfig = InArgs._BagConfigAsset; SelectedSkillAsset = nullptr; bIsPlacingSkill = false; SelectedSkillIndex = -1; ChildSlot [ SNew(SVerticalBox) // BagShapeAsset 选择器 + SVerticalBox::Slot() .AutoHeight() .Padding(5.0f) [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .AutoWidth() .VAlign(VAlign_Center) .Padding(0, 0, 10, 0) [ SNew(STextBlock) .Text(FText::FromString(TEXT("背包形状:"))) .Font(FCoreStyle::GetDefaultFontStyle("Bold", 10)) ] + SHorizontalBox::Slot() .FillWidth(1.0f) [ SNew(SObjectPropertyEntryBox) .ObjectPath_Lambda([this]() { return BagConfig.IsValid() && BagConfig->BagShapeAsset ? BagConfig->BagShapeAsset->GetPathName() : FString(); }) .AllowedClass(UBagShapeAsset::StaticClass()) .OnObjectChanged(this, &SBagConfigEditorWidget::OnBagShapeAssetChanged) .DisplayUseSelected(true) .DisplayBrowse(true) .DisplayThumbnail(false) ] ] // 技能资源 选择器 + SVerticalBox::Slot() .AutoHeight() .Padding(5.0f) [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .AutoWidth() .VAlign(VAlign_Center) .Padding(0, 0, 10, 0) [ SNew(STextBlock) .Text(FText::FromString(TEXT("选择要添加的技能:"))) .Font(FCoreStyle::GetDefaultFontStyle("Bold", 10)) ] + SHorizontalBox::Slot() .FillWidth(1.0f) [ SNew(SObjectPropertyEntryBox) .ObjectPath_Lambda([this]() { return SelectedSkillAsset.IsValid() ? SelectedSkillAsset->GetPathName() : FString(); }) .AllowedClass(USkillAsset::StaticClass()) .OnObjectChanged(this, &SBagConfigEditorWidget::OnSkillAssetChanged) .DisplayUseSelected(true) .DisplayBrowse(true) .DisplayThumbnail(false) ] ] // // 工具栏 // + SVerticalBox::Slot() // .AutoHeight() // .Padding(5.0f) // [ // SNew(SHorizontalBox) // // + SHorizontalBox::Slot() // .AutoWidth() // .Padding(2.0f) // [ // SNew(SButton) // .Text(FText::FromString(TEXT("Add Skill"))) // .OnClicked(this, &SBagClassEditor::OnAddSkillClicked) // .IsEnabled_Lambda([this]() { return BagClass.IsValid() && BagClass->BagShapeAsset != nullptr && SelectedSkillObject.IsValid(); }) // ] // // + SHorizontalBox::Slot() // .AutoWidth() // .Padding(2.0f) // [ // SNew(SButton) // .Text(FText::FromString(TEXT("Remove Selected"))) // .OnClicked(this, &SBagClassEditor::OnRemoveSkillClicked) // .IsEnabled_Lambda([this]() { return SelectedSkillObject.IsValid(); }) // ] // // + SHorizontalBox::Slot() // .AutoWidth() // .Padding(2.0f) // [ // SNew(SButton) // .Text(FText::FromString(TEXT("Clear All"))) // .OnClicked(this, &SBagClassEditor::OnClearAllSkillsClicked) // .IsEnabled_Lambda([this]() { return BagClass.IsValid() && BagClass->GetSkillCount() > 0; }) // ] // ] // // // 主编辑区域 // + SVerticalBox::Slot() // .FillHeight(1.0f) // [ // SNew(SSplitter) // .Orientation(Orient_Horizontal) // // // 左侧:背包格子视图 // + SSplitter::Slot() // .Value(0.7f) // [ // SNew(SBox) // .HAlign(HAlign_Center) // .VAlign(VAlign_Center) // .Padding(10.0f) // [ // SNew(SVerticalBox) // // + SVerticalBox::Slot() // .AutoHeight() // .HAlign(HAlign_Center) // .Padding(0, 0, 0, 10) // [ // SNew(STextBlock) // .Text_Lambda([this]() // { // if (!BagClass.IsValid()) // { // return FText::FromString(TEXT("No Bag Class")); // } // else if (!BagClass->BagShapeAsset) // { // return FText::FromString(TEXT("Please select a Bag Shape Asset above")); // } // else // { // return FText::FromString(FString::Printf(TEXT("Bag: %s (%dx%d)"), // *BagClass->BagShapeAsset->GetName(), // BagClass->BagShapeAsset->BagWidth, // BagClass->BagShapeAsset->BagHeight)); // } // }) // .Font(FCoreStyle::GetDefaultFontStyle("Bold", 12)) // .ColorAndOpacity_Lambda([this]() // { // return (!BagClass.IsValid() || !BagClass->BagShapeAsset) ? // FSlateColor(FLinearColor::Red) : FSlateColor(FLinearColor::White); // }) // ] // // + SVerticalBox::Slot() // .AutoHeight() // .HAlign(HAlign_Center) // [ // SAssignNew(BagGridWidget, SBagGridWidget) // .BagClass(BagClass.Get()) // .OnGridCellClicked(this, &SBagClassEditor::OnGridCellClicked) // .Visibility_Lambda([this]() // { // return (BagClass.IsValid() && BagClass->BagShapeAsset) ? // EVisibility::Visible : EVisibility::Hidden; // }) // ] // ] // ] // // // 右侧:技能列表 // + SSplitter::Slot() // .Value(0.3f) // [ // SNew(SVerticalBox) // // + SVerticalBox::Slot() // .AutoHeight() // .Padding(5.0f) // [ // SNew(STextBlock) // .Text(FText::FromString(TEXT("Placed Skills:"))) // .Font(FCoreStyle::GetDefaultFontStyle("Bold", 12)) // ] // // + SVerticalBox::Slot() // .FillHeight(1.0f) // .Padding(5.0f) // [ // SAssignNew(SkillListWidget, SSkillListWidget) // .BagClass(BagClass.Get()) // .OnSkillSelected(this, &SBagClassEditor::OnSkillSelected) // ] // ] //] ]; RefreshUI(); } void SBagConfigEditorWidget::OnBagShapeAssetChanged(const FAssetData& AssetData) { if (!BagConfig.IsValid()) { return; } // 获取新选择的BagShapeAsset UBagShapeAsset* NewBagShapeAsset = Cast(AssetData.GetAsset()); // 如果选择了不同的资源,清空现有技能并更新引用 if (BagConfig->BagShapeAsset != NewBagShapeAsset) { // 清空现有技能(因为新的背包形状可能不兼容) if (NewBagShapeAsset && BagConfig->GetSkillCount() > 0) { BagConfig->ClearAllSkills(); ShowWarningMessage(TEXT("Existing skills cleared due to bag shape change")); } // 更新BagShapeAsset引用 BagConfig->BagShapeAsset = NewBagShapeAsset; // 标记资源为已修改 BagConfig->MarkPackageDirty(); // 刷新UI RefreshUI(); if (NewBagShapeAsset) { ShowWarningMessage(FString::Printf(TEXT("Bag shape set to: %s"), *NewBagShapeAsset->GetName())); } else { ShowWarningMessage(TEXT("Bag shape asset cleared")); } } } void SBagConfigEditorWidget::OnSkillAssetChanged(const FAssetData& AssetData) { SelectedSkillAsset = Cast(AssetData.GetAsset()); } void SBagConfigEditorWidget::RefreshUI() { // if (BagGridWidget.IsValid()) // { // BagGridWidget->RefreshGrid(); // } // // if (SkillListWidget.IsValid()) // { // SkillListWidget->RefreshSkillList(); // } } void SBagConfigEditorWidget::ShowWarningMessage(const FString& Message) { FNotificationInfo Info(FText::FromString(Message)); Info.bFireAndForget = true; Info.FadeOutDuration = 3.0f; Info.ExpireDuration = 3.0f; FSlateNotificationManager::Get().AddNotification(Info); }