// Fill out your copyright notice in the Description page of Project Settings. #include "Widgets/BagShapeEditorWidget.h" #include "Widgets/Input/SSpinBox.h" #include "EditorStyleSet.h" void SShapeEditorWidget::Construct(const FArguments& InArgs) { BagShapeAsset = InArgs._BagShapeAsset; ChildSlot [ SNew(SSplitter) .Orientation(Orient_Vertical) + SSplitter::Slot() .Value(0.2f) [ CreateSizeControls() ] + SSplitter::Slot() .Value(0.1f) [ CreateGridControls() ] + SSplitter::Slot() .Value(0.7f) [ SNew(SScrollBox) + SScrollBox::Slot() [ SNew(SBorder) .BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder")) .Padding(10.0f) [ SNew(SBox) .HAlign(HAlign_Center) .VAlign(VAlign_Center) [ SAssignNew(GridWidget, SShapeGridWidget) .BagShapeAsset(BagShapeAsset.Get()) .OnSlotClicked(this, &SShapeEditorWidget::OnSlotClicked) ] ] ] ] ]; } void SShapeEditorWidget::RefreshGrid() { if (GridWidget.IsValid()) { GridWidget->UpdateBagShapeAsset(BagShapeAsset.Get()); } } TSharedRef SShapeEditorWidget::CreateSizeControls() { return SNew(SBorder) .BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder")) .Padding(10.0f) [ SNew(SVerticalBox) + SVerticalBox::Slot() .AutoHeight() .Padding(0, 5) [ SNew(STextBlock) .Text(FText::FromString("Bag Size Settings")) .Font(FCoreStyle::GetDefaultFontStyle("Bold", 14)) ] + SVerticalBox::Slot() .AutoHeight() .Padding(0, 5) [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .AutoWidth() .VAlign(VAlign_Center) .Padding(0, 0, 10, 0) [ SNew(STextBlock) .Text(FText::FromString("Width:")) ] + SHorizontalBox::Slot() .AutoWidth() [ SNew(SBox) .WidthOverride(100.0f) [ SNew(SSpinBox) .MinValue(1) .MaxValue(10) .Value(this, &SShapeEditorWidget::GetShapeWidth) .OnValueChanged(this, &SShapeEditorWidget::OnWidthChanged) ] ] + SHorizontalBox::Slot() .AutoWidth() .VAlign(VAlign_Center) .Padding(20, 0, 10, 0) [ SNew(STextBlock) .Text(FText::FromString("Height:")) ] + SHorizontalBox::Slot() .AutoWidth() [ SNew(SBox) .WidthOverride(100.0f) [ SNew(SSpinBox) .MinValue(1) .MaxValue(10) .Value(this, &SShapeEditorWidget::GetShapeHeight) .OnValueChanged(this, &SShapeEditorWidget::OnHeightChanged) ] ] ] ]; } int32 SShapeEditorWidget::GetShapeWidth() const { return BagShapeAsset.IsValid() ? BagShapeAsset->ShapeWidth : 5; } int32 SShapeEditorWidget::GetShapeHeight() const { return BagShapeAsset.IsValid() ? BagShapeAsset->ShapeHeight : 5; } void SShapeEditorWidget::OnWidthChanged(int32 NewWidth) { if (BagShapeAsset.IsValid() && NewWidth != BagShapeAsset->ShapeWidth) { BagShapeAsset->ShapeWidth = NewWidth; BagShapeAsset->InitializeShape(); BagShapeAsset->MarkPackageDirty(); RefreshGrid(); } } void SShapeEditorWidget::OnHeightChanged(int32 NewHeight) { if (BagShapeAsset.IsValid() && NewHeight != BagShapeAsset->ShapeHeight) { BagShapeAsset->ShapeHeight = NewHeight; BagShapeAsset->InitializeShape(); BagShapeAsset->MarkPackageDirty(); RefreshGrid(); } } TSharedRef SShapeEditorWidget::CreateGridControls() { return SNew(SBorder) .BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder")) .Padding(10.0f) [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .AutoWidth() .Padding(0, 0, 10, 0) [ SNew(SButton) .Text(FText::FromString("All Enable")) .OnClicked(this, &SShapeEditorWidget::OnAllEnableClicked) ] + SHorizontalBox::Slot() .AutoWidth() .Padding(0, 0, 10, 0) [ SNew(SButton) .Text(FText::FromString("All Disable")) .OnClicked(this, &SShapeEditorWidget::OnAllDisableClicked) ] ]; } FReply SShapeEditorWidget::OnAllEnableClicked() { if (BagShapeAsset.IsValid()) { BagShapeAsset->InitializeShape(); BagShapeAsset->MarkPackageDirty(); RefreshGrid(); RefreshThumbnail(); } return FReply::Handled(); } FReply SShapeEditorWidget::OnAllDisableClicked() { if (BagShapeAsset.IsValid()) { for (int32 X = 0; X < BagShapeAsset->ShapeWidth; X++) { for (int32 Y = 0; Y < BagShapeAsset->ShapeHeight; Y++) { BagShapeAsset->SetSlotActive(X, Y, false); } } BagShapeAsset->MarkPackageDirty(); RefreshGrid(); RefreshThumbnail(); } return FReply::Handled(); } void SShapeEditorWidget::OnSlotClicked(int32 X, int32 Y) { if (!BagShapeAsset.IsValid()) { return; } bool bCurrentState = BagShapeAsset->IsSlotActive(X, Y); BagShapeAsset->SetSlotActive(X, Y, !bCurrentState); // Refresh the grid widget if (GridWidget.IsValid()) { GridWidget->UpdateBagShapeAsset(BagShapeAsset.Get()); } // Mark the asset as modified BagShapeAsset->MarkPackageDirty(); // 强制刷新缩略图 RefreshThumbnail(); } void SShapeEditorWidget::RefreshThumbnail() { if (!BagShapeAsset.IsValid()) { return; } // 强制资源重新生成缩略图的最可靠方法 //BagShapeAsset->MarkPackageDirty(); // // 触发完整的PostEditChange流程 // FPropertyChangedEvent PropertyChangedEvent(nullptr); // BagShapeAsset->PostEditChangeProperty(PropertyChangedEvent); // // // 通知系统资源已修改 if (GEditor) { GEditor->GetEditorSubsystem()->BroadcastAssetPostImport(nullptr, BagShapeAsset.Get()); } }