特效卡兼容改名等

This commit is contained in:
Sch 2023-08-03 18:28:37 +08:00
parent 099040a36f
commit 0b5c87e4e2
11 changed files with 319 additions and 63 deletions

View File

@ -39,6 +39,7 @@ public:
virtual void ExportProject(const FString& ExportPath) {};
virtual void ImportProject(const FString& ImportPath) {};
virtual void NewProject(const FString& NewPath){};
virtual void SaveProject() {};
virtual FString GetGroupName(TSharedPtr<class IWidgetInterface> WidgetInterface) { return FString(); };
virtual FTimelinePropertyData* GetResourcePropertyDataPtr(FGuid GUID) { return nullptr; };
@ -47,5 +48,6 @@ public:
virtual void OnRemoveCard(const FGuid& SelectedCard) {};
virtual void UpdateProperties(IPropertiesInterface* Interface) {};
virtual void ClearProperties() {};
FGuid CurrentSelectedPropertiesInterfaceGuid;
};

View File

@ -29,4 +29,6 @@ public:
virtual TSharedPtr<SWidget> GetPropertiesWidget() { return nullptr; };
FGuid PropertiesInterfaceGUID = FGuid::NewGuid();
TSharedPtr<SWidget> PropertiesWidget;
};

View File

@ -127,13 +127,9 @@ void SCurtainPanel::Construct(const FArguments& InArgs)
SNew(SButton)
.OnClicked_Lambda([this]()
{
TArray<FString> Path;
IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
DesktopPlatform->OpenFileDialog(nullptr, (TEXT("打开文件")), TEXT(""), TEXT(""), TEXT(""), EFileDialogFlags::None, Path);
MainWidgetInterface->OpenTimeline(Path[0], false);
return FReply::Handled();
})
.Text(FText::FromString(TEXT("测试-直接导入时间轴bin")))
.Text(FText::FromString(TEXT("保存项目")))
]
]

View File

@ -26,6 +26,7 @@ public:
inline static float GlobalFPS = 30.0f;
inline static FString CurrentProjectName = "DefaultProject";
inline static FString BasePath = FPaths::ProjectDir();
inline static FString Version = "1.0.0";
static int32 GetAlignOfTickSpace(double Align, bool bCeil = false)
{
return bCeil ? FMath::CeilToInt(Align / FGlobalData::DefaultTimeTickSpace) * FGlobalData::DefaultTimeTickSpace :
@ -289,11 +290,13 @@ struct CUT5_API FEffectCardProperty
FString Name = "";
FTimelineInfo TimelineInfo;
bool bIsActive = false;
int32 ID = 0;
friend FArchive& operator<<(FArchive& Ar, FEffectCardProperty& EffectCardProperty)
{
Ar << EffectCardProperty.Guid;
Ar << EffectCardProperty.Name;
Ar << EffectCardProperty.TimelineInfo;
Ar << EffectCardProperty.ID;
return Ar;
};
};
@ -308,6 +311,7 @@ struct CUT5_API FEffectCardGroup
bool bIsActive = false;
FGuid Guid = FGuid::NewGuid();
FTimelineInfo TimelineInfo;
int32 ID = 0;
friend FArchive& operator<<(FArchive& Ar, FEffectCardGroup& EffectCard)
{
Ar << EffectCard.GroupName;
@ -317,6 +321,7 @@ struct CUT5_API FEffectCardGroup
Ar << EffectCard.bIsExpanded;
Ar << EffectCard.Guid;
Ar << EffectCard.TimelineInfo;
Ar << EffectCard.ID;
return Ar;
};
};
@ -330,6 +335,14 @@ public:
TArray<TSharedPtr<FCurtain>> ChildrenCurtain;
};
class FCurtainTree
{
public:
FString CurtainTreeName = TEXT("新建幕");
FGuid CurtainUUID;
};
struct FGeneralPropertyBase
{
FString PropertyName;

View File

@ -76,6 +76,8 @@ void SEffectCard::Construct(const FArguments& InArgs)
{
const FString Name = FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName, TEXT("FX"), GroupProperty->GroupName + TEXT(".bin"));
MainInterface->OpenTimeline(Name, true);
MainInterface->CurrentSelectedPropertiesInterfaceGuid = GroupProperty->Guid;
MainInterface->UpdateProperties(this);
MainInterface->OnSelectCard(GroupProperty->Guid);
}
return FReply::Handled();
@ -104,6 +106,7 @@ void SEffectCard::Construct(const FArguments& InArgs)
.HAlign(HAlign_Center)
[
SNew(SInlineEditableTextBlock)
.Visibility(GroupProperty->bIsDedicated ? CardProperty->bIsActive ? EVisibility::HitTestInvisible : EVisibility::Visible : EVisibility::Visible)
.Text(FText::FromString(CardProperty->Name))
.OnVerifyTextChanged_Lambda([this](const FText& NewText, FText& OutErrorMessage)
{
@ -134,50 +137,7 @@ void SEffectCard::Construct(const FArguments& InArgs)
]
];
PropertiesWidget = SNew(SBox).HeightOverride(32).WidthOverride(214)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.SizeParam(FAuto())
[
SNew(SBox)
.WidthOverride(62)
.HeightOverride(32)
[
SNew(STextBlock)
.Text(FText::FromString(TEXT("名称")))
]
]
+ SHorizontalBox::Slot()
.SizeParam(FAuto())
[
SNew(SBox)
.WidthOverride(136)
.HeightOverride(32)
[
SNew(SEditableTextBox)
.Text(FText::FromString(CardProperty->Name))
.OnVerifyTextChanged_Lambda([this](const FText& InText, FText& OutErrorMessage)
{
TArray<FEffectCardProperty> Properties = GroupProperty->Cards;
for (FEffectCardProperty NewCardProperty : Properties)
{
if (NewCardProperty.Name == InText.ToString() && NewCardProperty.Guid != this->CardProperty->Guid)
{
OutErrorMessage = FText::FromString(TEXT("名称已存在"));
return false;
}
}
return true;
})
.OnTextCommitted_Lambda([this](const FText& InText, ETextCommit::Type InCommitType)
{
this->OnNameEdited(InText.ToString(), CardProperty->Name);
})
]
]
];
PropertiesInterfaceGUID = CardProperty->Guid;
}
@ -233,13 +193,117 @@ void SEffectCard::OnMouseLeave(const FPointerEvent& MouseEvent)
FProperties* SEffectCard::GetProperties()
{
Properties = new FProperties();
Properties->AddCardNameProperties(TEXT("名称"), &CardProperty->Name)->AddNumProperties(TEXT("ID"), &ID);
return Properties;
}
TSharedPtr<SWidget> SEffectCard::GetPropertiesWidget()
{
PropertiesWidget =
SNew(SVerticalBox)
+ SVerticalBox::Slot()
[
SNew(SBox).HeightOverride(32).WidthOverride(214)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.SizeParam(FAuto())
[
SNew(SBox)
.WidthOverride(62)
.HeightOverride(32)
[
SNew(STextBlock)
.Text(FText::FromString(TEXT("名称")))
]
]
+ SHorizontalBox::Slot()
.SizeParam(FAuto())
[
SNew(SBox)
.WidthOverride(136)
.HeightOverride(32)
[
SNew(SEditableTextBox)
.Text(FText::FromString(CardProperty->Name))
.OnVerifyTextChanged_Lambda([this](const FText& InText, FText& OutErrorMessage)
{
TArray<FEffectCardProperty> Properties = GroupProperty->Cards;
for (FEffectCardProperty NewCardProperty : Properties)
{
if (NewCardProperty.Name == InText.ToString() && NewCardProperty.Guid != this->CardProperty->Guid)
{
OutErrorMessage = FText::FromString(TEXT("名称已存在"));
return false;
}
}
if (this->GroupProperty->bIsDedicated ? this->CardProperty->bIsActive : false)
{
OutErrorMessage = FText::FromString(TEXT("选中时不可以修改名称"));
return false;
}
return true;
})
.OnTextCommitted_Lambda([this](const FText& InText, ETextCommit::Type InCommitType)
{
this->OnNameEdited(InText.ToString(), CardProperty->Name);
})
]
]
]
]
+ SVerticalBox::Slot()
[
SNew(SBox).HeightOverride(32).WidthOverride(214)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.SizeParam(FAuto())
[
SNew(SBox)
.WidthOverride(62)
.HeightOverride(32)
[
SNew(STextBlock)
.Text(FText::FromString(TEXT("ID")))
]
]
+ SHorizontalBox::Slot()
.SizeParam(FAuto())
[
SNew(SBox)
.WidthOverride(136)
.HeightOverride(32)
[
SNew(SEditableTextBox)
.Text(FText::FromString(FString::FromInt(GroupProperty->ID)))
.OnVerifyTextChanged_Lambda([this](const FText& InText, FText& OutErrorMessage)
{
if (InText.IsEmpty())
{
OutErrorMessage = FText::FromString(TEXT("ID不能为空"));
return false;
}
// ID必须是数字
for (TCHAR Char : InText.ToString())
{
if (!FChar::IsDigit(Char))
{
OutErrorMessage = FText::FromString(TEXT("ID必须是数字"));
return false;
}
}
return true;
})
.OnTextCommitted_Lambda([this](const FText& InText, ETextCommit::Type InCommitType)
{
GroupProperty->ID = FCString::Atoi(*InText.ToString());
})
]
]
]
];
return PropertiesWidget;
}

View File

@ -50,9 +50,8 @@ public:
virtual FProperties* GetProperties() override;
virtual TSharedPtr<SWidget> GetPropertiesWidget() override;
TSharedPtr<SWidget> PropertiesWidget;
FString CardName;
int32 ID;
};

View File

@ -4,20 +4,23 @@
#include "SEffectCardGroup.h"
#include "SEffectCard.h"
#include "SEffectCardsPanel.h"
#include "SlateOptMacros.h"
#include "Cut5/Utils/Utils.h"
#include "Cut5/Widgets/MicroWidgets/SClickEditableText.h"
#include "Widgets/Layout/SExpandableArea.h"
#include "Widgets/Layout/SGridPanel.h"
#include "Widgets/Layout/SScrollBox.h"
#include "Widgets/Text/SInlineEditableTextBlock.h"
#include "Cut5/Widgets/FX/SEffectCardsPanel.h"
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SEffectCardGroup::OnNameEdited(FString New, FString Old)
{
EffectCardGroup->GroupName = New;
TextBlock->SetText(FText::FromString(New));
if (!IFileManager::Get().FileExists(*FUtils::GroupFullPath(EffectCardGroup->GroupName)))
{
TArray<uint8> BinaryData;
@ -40,6 +43,7 @@ void SEffectCardGroup::Construct(const FArguments& InArgs)
{
EffectCardGroup = InArgs._EffectCardGroup;
MainInterface = InArgs._MainInterface;
EffectCardPanel = InArgs._EffectCardPanel;
// 只考虑组别储存,不考虑组内卡片储存
SetSavePath({TEXT("FX"), EffectCardGroup->GroupName + TEXT(".bin")});
@ -83,6 +87,8 @@ void SEffectCardGroup::Construct(const FArguments& InArgs)
{
const FString Name = FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName, TEXT("FX"), EffectCardGroup->GroupName + TEXT(".bin"));
MainInterface->OpenTimeline(Name, true);
MainInterface->CurrentSelectedPropertiesInterfaceGuid = EffectCardGroup->Guid;
MainInterface->UpdateProperties(this);
MainInterface->OnSelectCard(EffectCardGroup->Guid);
}
return FReply::Handled();
@ -96,7 +102,7 @@ void SEffectCardGroup::Construct(const FArguments& InArgs)
+ SVerticalBox::Slot()
.SizeParam(FAuto())
[
SNew(SInlineEditableTextBlock)
SAssignNew(TextBlock, SInlineEditableTextBlock)
.Text(FText::FromString(EffectCardGroup->GroupName))
.OnVerifyTextChanged_Lambda([](const FText& Text, FText& OutErrorMessage)
{
@ -108,7 +114,7 @@ void SEffectCardGroup::Construct(const FArguments& InArgs)
OnNameEdited(Text.ToString(), TEXT(""));
})
.Visibility(EffectCardGroup->bIsDedicated ? EVisibility::Collapsed : EVisibility::Visible)
.Visibility((EffectCardGroup->bIsDedicated ? EVisibility::Collapsed : EVisibility::Visible) == EVisibility::Visible ? EffectCardGroup->bIsActive ? EVisibility::HitTestInvisible : EVisibility::Visible : EVisibility::Collapsed)
]
+ SVerticalBox::Slot()
[
@ -125,14 +131,117 @@ void SEffectCardGroup::Construct(const FArguments& InArgs)
]
]
];
PropertiesWidget =
SNew(SVerticalBox)
+ SVerticalBox::Slot()
[
SNew(SBox).HeightOverride(32).WidthOverride(214)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.SizeParam(FAuto())
[
SNew(SBox)
.WidthOverride(62)
.HeightOverride(32)
[
SNew(STextBlock)
.Text(FText::FromString(TEXT("名称")))
]
]
+ SHorizontalBox::Slot()
.SizeParam(FAuto())
[
SNew(SBox)
.WidthOverride(136)
.HeightOverride(32)
[
SNew(SEditableTextBox)
.Text(FText::FromString(EffectCardGroup->GroupName))
.OnVerifyTextChanged_Lambda([this](const FText& InText, FText& OutErrorMessage)
{
TArray<FEffectCardProperty> Properties = EffectCardGroup->Cards;
for (FEffectCardProperty NewCardProperty : Properties)
{
if (NewCardProperty.Name == InText.ToString() && NewCardProperty.Guid != this->EffectCardGroup->Guid)
{
OutErrorMessage = FText::FromString(TEXT("名称已存在"));
return false;
}
}
if (this->EffectCardGroup->bIsActive == true)
{
OutErrorMessage = FText::FromString(TEXT("选中时不可以修改名称"));
return false;
}
return true;
})
.OnTextCommitted_Lambda([this](const FText& InText, ETextCommit::Type InCommitType)
{
this->OnNameEdited(InText.ToString(), EffectCardGroup->GroupName);
})
]
]
]
]
+ SVerticalBox::Slot()
[
SNew(SBox).HeightOverride(32).WidthOverride(214)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.SizeParam(FAuto())
[
SNew(SBox)
.WidthOverride(62)
.HeightOverride(32)
[
SNew(STextBlock)
.Text(FText::FromString(TEXT("ID")))
]
]
+ SHorizontalBox::Slot()
.SizeParam(FAuto())
[
SNew(SBox)
.WidthOverride(136)
.HeightOverride(32)
[
SNew(SEditableTextBox)
.Text(FText::FromString(FString::FromInt(EffectCardGroup->ID)))
.OnVerifyTextChanged_Lambda([this](const FText& InText, FText& OutErrorMessage)
{
if (InText.IsEmpty())
{
OutErrorMessage = FText::FromString(TEXT("ID不能为空"));
return false;
}
// ID必须是数字
for (TCHAR Char : InText.ToString())
{
if (!FChar::IsDigit(Char))
{
OutErrorMessage = FText::FromString(TEXT("ID必须是数字"));
return false;
}
}
return true;
})
.OnTextCommitted_Lambda([this](const FText& InText, ETextCommit::Type InCommitType)
{
EffectCardGroup->ID = FCString::Atoi(*InText.ToString());
})
]
]
]
];
PropertiesInterfaceGUID = EffectCardGroup->Guid;
CallRender();
}
void SEffectCardGroup::CallRender()
{
// MainInterface->UpdateProperties(nullptr);
MainInterface->UpdateProperties(nullptr);
CardsInst.Empty();
GridPanel->ClearChildren();
GridPanel->AddSlot(GridPanel->GetChildren()->Num() % 3, GridPanel->GetChildren()->Num() / 3)
@ -185,10 +294,14 @@ void SEffectCardGroup::CallRender()
}
CardsInst.Add(NewCardInst);
}
}
TSharedPtr<SWidget> SEffectCardGroup::GetPropertiesWidget()
{
return PropertiesWidget;
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

View File

@ -13,7 +13,7 @@
/**
*
*/
class CUT5_API SEffectCardGroup : public SCompoundWidget, public ISaveInterface
class CUT5_API SEffectCardGroup : public SCompoundWidget, public ISaveInterface, public IPropertiesInterface
{
public:
SLATE_BEGIN_ARGS(SEffectCardGroup)
@ -21,6 +21,7 @@ public:
}
SLATE_ARGUMENT(FEffectCardGroup*, EffectCardGroup)
SLATE_ARGUMENT(ICutMainWidgetInterface*, MainInterface)
SLATE_ARGUMENT(class SEffectCardsPanel*, EffectCardPanel)
SLATE_END_ARGS()
void OnNameEdited(FString New, FString Old);
@ -32,6 +33,8 @@ public:
ICutMainWidgetInterface* MainInterface;
FEffectCardGroup* EffectCardGroup;
class SEffectCardsPanel* EffectCardPanel = nullptr;
/**
* @brief All the effect cards slate instance in this group.
@ -43,5 +46,14 @@ public:
*/
TSharedPtr<SGridPanel> GridPanel;
TSharedPtr<SInlineEditableTextBlock> TextBlock;
TArray<TSharedPtr<class SEffectCard>> CardsInst;
virtual TSharedPtr<SWidget> GetPropertiesWidget() override;
TSharedPtr<SWidget> PropertiesWidget;
};

View File

@ -53,12 +53,18 @@ void SEffectCardsPanel::CallRender()
ScrollBox->ClearChildren();
for (FEffectCardGroup& Group : EffectCardGroups)
{
ScrollBox->AddSlot()
[
TSharedPtr<SEffectCardGroup> CardGroupInst =
SNew(SEffectCardGroup)
.EffectCardGroup(&Group)
.MainInterface(MainInterface)
.MainInterface(MainInterface);
ScrollBox->AddSlot()
[
CardGroupInst.ToSharedRef()
];
if (MainInterface->CurrentSelectedPropertiesInterfaceGuid == Group.Guid)
{
MainInterface->UpdateProperties(CardGroupInst.Get());
}
}
ScrollBox->AddSlot()
[
@ -205,6 +211,7 @@ void SEffectCardsPanel::SelectCard(const FGuid& Guid)
CurrentSelectedCardGuid.Invalidate();
DeselectedAll();
MainInterface->UpdateProperties(nullptr);
MainInterface->ClearProperties();
CallRender();
}
else

View File

@ -526,6 +526,46 @@ void SCutMainWindow::NewProject(const FString& NewPath)
CutTimeline->TimelineInfo.CurrentOpenFullPath = FUtils::MainSaveFullPath();
}
void SCutMainWindow::SaveProject()
{
// 保存架构
// 保存只保存项目文件与导出的xml不相关联。
// 根 --- 项目关联文件 项目名.cutlink
// 根 << 版本号
// 根 << 记录所有导入资产链接
// 根 << 记录所有幕
// 根 << 记录所有组轨道链接
// 新建项目关联文件.cutlink
TArray<uint8> ProjectLinkData;
FMemoryWriter MemoryWriter(ProjectLinkData);
// 写入版本号
MemoryWriter << FGlobalData::Version;
// 记录所有导入资产链接
int32 PropertiesLength = CustomInputPanel->PropertyData.Num();
MemoryWriter << PropertiesLength;
for (int32 i = 0; i < PropertiesLength; i++)
{
MemoryWriter << CustomInputPanel->PropertyData[i];
}
// 记录所有幕
// 记录所有组轨道链接
int32 GroupLength = EffectCardsPanel->EffectCardGroups.Num();
MemoryWriter << GroupLength;
for (FEffectCardGroup& Group : EffectCardsPanel->EffectCardGroups)
{
MemoryWriter << Group;
}
FFileHelper::SaveArrayToFile(ProjectLinkData, *FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName + TEXT(".cutlink")));
}
void SCutMainWindow::OnSelectCard(const FGuid& SelectedCard)
{
if (SelectedCard.IsValid())
@ -587,5 +627,11 @@ void SCutMainWindow::UpdateProperties(IPropertiesInterface* Interface)
}
void SCutMainWindow::ClearProperties()
{
CurrentSelectedPropertiesInterfaceGuid.Invalidate();
CustomPanel->UpdateProperties(nullptr);
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

View File

@ -58,11 +58,13 @@ public:
virtual void ExportProject(const FString& ExportPath) override;
virtual void ImportProject(const FString& ImportPath) override;
virtual void NewProject(const FString& NewPath) override;
virtual void SaveProject() override;
virtual void OnSelectCard(const FGuid& SelectedCard) override;
virtual void OnRemoveCard(const FGuid& SelectedCard) override;
virtual FTimelinePropertyData* GetResourcePropertyDataPtr(FGuid GUID) override;
virtual FString GetGroupName(TSharedPtr<IWidgetInterface> WidgetInterface) override;
virtual void UpdateProperties(IPropertiesInterface* Interface) override;
virtual void ClearProperties() override;
};