8.24.1
1. 微调 O 3. ctrls手动保存 O 4. 独立特效卡永久保存,拖拽进组和特效卡会复制特效卡,复制卡片与原本卡片共享,只有删除原本卡片复制卡片才会消失 O 5. 组合卡片没有轨道 O 6. 拖拽全选坐标计算 7. 拖拽动画 8. 拉条更新指针动画 O 9. wav无法读取 10. 右键资产删除 O 11. 单选择改为被迫全选 O 12. 固定帧数 13. 预设片段实例保存 14. 剪刀显示时间码 O 15. 删除自定义预设会导致崩溃
This commit is contained in:
parent
fa8ecab21f
commit
de15282a40
@ -166,9 +166,9 @@ TArray<FEncodeVideoInfo> FUtils::TrackEncodeVideo(const FTrackData& TrackData, c
|
||||
|
||||
FString StartTime = FString::Printf(TEXT("%02d:%02d:%02d"), StartTimespan.GetHours(), StartTimespan.GetMinutes(), StartTimespan.GetSeconds());
|
||||
FString EndTime = FString::Printf(TEXT("%02d:%02d:%02d"), EndTimespan.GetHours(), EndTimespan.GetMinutes(), EndTimespan.GetSeconds());
|
||||
FString InputFile = TempClipData.ResourcePropertyDataPtr->MoviePath;
|
||||
FString InputFile = "\"" + TempClipData.ResourcePropertyDataPtr->MoviePath + "\"";
|
||||
|
||||
FString OutputFile = FPaths::ConvertRelativePathToFull(ExportPath + FString::FromInt(i) + TEXT(".mp4"));
|
||||
FString OutputFile = "\"" + FPaths::ConvertRelativePathToFull(ExportPath + FString::FromInt(i) + TEXT(".mp4")) + "\"";
|
||||
|
||||
int32 StartFrame = (TempClipData.VideoStartFrame) % static_cast<int>(FGlobalData::GlobalFPS);;
|
||||
int32 EndFrame = (TempClipData.VideoEndFrame) % static_cast<int>(FGlobalData::GlobalFPS);
|
||||
@ -183,6 +183,10 @@ TArray<FEncodeVideoInfo> FUtils::TrackEncodeVideo(const FTrackData& TrackData, c
|
||||
EncodeVideoInfo.EncodedVideoName = ExportPath + FString::FromInt(i) + TEXT(".mp4");
|
||||
EncodeVideoInfo.ClipStartFrame = TempClipData.ClipStartFrame;
|
||||
EncodeVideoInfo.ClipEndFrame = TempClipData.ClipEndFrame;
|
||||
|
||||
EncodeVideoInfo.TrackData = TrackData;
|
||||
EncodeVideoInfo.ClipData = TempClipData;
|
||||
|
||||
EncodeVideoInfos.Add(EncodeVideoInfo);
|
||||
}
|
||||
i++;
|
||||
@ -241,6 +245,9 @@ TArray<FEncodeVideoInfo> FUtils::TrackEncodeAudio(const FTrackData& TrackData, c
|
||||
EncodeVideoInfo.EncodedVideoName = ExportPath + FString::FromInt(i) + TEXT(".mp3");
|
||||
EncodeVideoInfo.ClipStartFrame = TempClipData.ClipStartFrame;
|
||||
EncodeVideoInfo.ClipEndFrame = TempClipData.ClipEndFrame;
|
||||
|
||||
EncodeVideoInfo.TrackData = TrackData;
|
||||
EncodeVideoInfo.ClipData = TempClipData;
|
||||
EncodeVideoInfos.Add(EncodeVideoInfo);
|
||||
}
|
||||
i++;
|
||||
@ -496,6 +503,9 @@ TArray<FEncodeVideoInfo> FUtils::ExportPsaf(FTrackData TrackData, const FString&
|
||||
FEncodeVideoInfo EncodeVideoInfo;
|
||||
EncodeVideoInfo.EncodedVideoName = ExportName + FString::FromInt(i) + ".psaf";
|
||||
EncodeVideoInfo.EncodedVideoTimeCode = FGlobalData::GetTimeData(TempClipData.ClipStartFrame);
|
||||
|
||||
EncodeVideoInfo.TrackData = TrackData;
|
||||
EncodeVideoInfo.ClipData = TempClipData;
|
||||
EncodeVideoInfos.Add(EncodeVideoInfo);
|
||||
i++;
|
||||
}
|
||||
|
8
Source/Cut5/Widgets/Commands/CustomResourceCommands.cpp
Normal file
8
Source/Cut5/Widgets/Commands/CustomResourceCommands.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#include "CustomResourceCommands.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FCurtainCommands"
|
||||
void FCustomResourceCommands::RegisterCommands()
|
||||
{
|
||||
UI_COMMAND(Delete, "删除", "Executes My FCurtainCommands", EUserInterfaceActionType::Button, FInputChord());
|
||||
}
|
||||
#undef LOCTEXT_NAMESPACE
|
12
Source/Cut5/Widgets/Commands/CustomResourceCommands.h
Normal file
12
Source/Cut5/Widgets/Commands/CustomResourceCommands.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
class FCustomResourceCommands : public TCommands<FCustomResourceCommands>
|
||||
{
|
||||
public:
|
||||
FCustomResourceCommands() : TCommands<FCustomResourceCommands>(TEXT("FCustomResourceCommands"), NSLOCTEXT("Contexts", "FCurtainCommands", "FCurtainCommands"), NAME_None, FAppStyle::GetAppStyleSetName())
|
||||
{
|
||||
}
|
||||
virtual void RegisterCommands() override;
|
||||
|
||||
TSharedPtr<FUICommandInfo> Delete;
|
||||
};
|
@ -29,4 +29,7 @@ public:
|
||||
TSharedPtr<FUICommandInfo> Copy;
|
||||
TSharedPtr<FUICommandInfo> Paste;
|
||||
|
||||
TSharedPtr<FUICommandInfo> MicroLeft;
|
||||
TSharedPtr<FUICommandInfo> MicroRight;
|
||||
|
||||
};
|
||||
|
@ -22,5 +22,8 @@ void FShortCutCommands::RegisterCommands()
|
||||
|
||||
UI_COMMAND(Copy, "复制", "Executes Start Garbage Collect", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::C, EModifierKey::Control));
|
||||
UI_COMMAND(Paste, "粘贴", "Executes End Garbage Collect", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::V, EModifierKey::Control));
|
||||
|
||||
UI_COMMAND(MicroLeft, "左微调", "Executes My FCurtainCommands", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::Left));
|
||||
UI_COMMAND(MicroRight, "右微调", "Executes My FCurtainCommands", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::Right));
|
||||
}
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
@ -31,7 +31,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";
|
||||
inline static FString Version = "1.0.1";
|
||||
inline static FString ExportPath = "";
|
||||
|
||||
inline static TArray<FColor> Colors =
|
||||
@ -97,6 +97,11 @@ struct FStringWithGUID
|
||||
{
|
||||
return this->Guid == Other.Guid;
|
||||
}
|
||||
|
||||
bool operator==(const FGuid& OtherGuid) const
|
||||
{
|
||||
return this->Guid == OtherGuid;
|
||||
}
|
||||
};
|
||||
|
||||
enum class ETrackType
|
||||
@ -168,6 +173,7 @@ struct CUT5_API FTrackData
|
||||
Ar << TrackData.TrackNum;
|
||||
Ar << TrackData.ClipData;
|
||||
Ar << TrackData.DeviceTrack;
|
||||
Ar << TrackData.IsMute;
|
||||
return Ar;
|
||||
};
|
||||
|
||||
@ -178,6 +184,8 @@ struct CUT5_API FTrackData
|
||||
int32 TrackNum = 1;
|
||||
FDeviceTrack DeviceTrack = FDeviceTrack("None", ETrackType::VideoTrack);
|
||||
TArray<FClipData> ClipData;
|
||||
|
||||
bool IsMute = false;
|
||||
};
|
||||
struct CUT5_API FCursorData
|
||||
{
|
||||
@ -250,6 +258,7 @@ struct CUT5_API FPresetsCustomData
|
||||
None,
|
||||
Breathe,
|
||||
Flash,
|
||||
Gradient,
|
||||
};
|
||||
|
||||
TArray<FLinearColor> Colors = { FLinearColor(1, 1 , 1) };
|
||||
@ -920,6 +929,9 @@ struct FEncodeVideoInfo
|
||||
FString EncodedVideoTimeCode = "00:00:00:00";
|
||||
int32 ClipStartFrame = 0;
|
||||
int32 ClipEndFrame = 0;
|
||||
|
||||
FTrackData TrackData;
|
||||
FClipData ClipData;
|
||||
};
|
||||
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include "AudioDevice.h"
|
||||
#include "Commands/CustomResourceCommands.h"
|
||||
|
||||
#include "Cut5/Interface/SoundInterface.h"
|
||||
#include "Cut5/Utils/FFMPEGUtils.h"
|
||||
@ -259,7 +260,7 @@ void SCustomInputPanel::Construct(const FArguments& InArgs)
|
||||
continue;
|
||||
};
|
||||
|
||||
TSharedPtr<SCustomInputResource> Resource = SNew(SCustomInputResource).MainInterface(MainWidgetInterface)
|
||||
TSharedPtr<SCustomInputResource> Resource = SNew(SCustomInputResource).MainInterface(MainWidgetInterface).CustomInputPanel(this)
|
||||
.PropertyData(Data).OnCheckBoxChecked_Lambda([this](FTimelinePropertyData& ClickedData, bool bIsChecked)
|
||||
{
|
||||
if (bIsChecked == true)
|
||||
@ -346,6 +347,30 @@ void SCustomInputPanel::Construct(const FArguments& InArgs)
|
||||
AddPreset(TEXT("启动投影"), TEXT(""), EPresetType::EnableProjector);
|
||||
AddPreset(TEXT("屏蔽投影"), TEXT(""), EPresetType::DisableProjector);
|
||||
|
||||
FCustomResourceCommands::Register();
|
||||
CommandList = MakeShareable(new FUICommandList);
|
||||
CommandList->MapAction(FCustomResourceCommands::Get().Delete, FExecuteAction::CreateLambda([this]()
|
||||
{
|
||||
int32 i = 0;
|
||||
for (FTimelinePropertyData& TimelinePropertyData : PropertyData)
|
||||
{
|
||||
if (TimelinePropertyData.Guid == SelectMenuProperty)
|
||||
{
|
||||
PropertyData.RemoveAt(i);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
for (TSharedPtr<SCustomInputResource> Resource : ResourceInst)
|
||||
{
|
||||
if (Resource->PropertyData.Guid == SelectMenuProperty)
|
||||
{
|
||||
GridPanel->RemoveSlot(Resource.ToSharedRef());
|
||||
break;
|
||||
}
|
||||
}
|
||||
SelectMenuProperty.Invalidate();
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
@ -361,6 +386,7 @@ FReply SCustomInputPanel::OnDrop(const FGeometry& MyGeometry, const FDragDropEve
|
||||
EffectGridPanel->AddSlot(EffectGridPanel->GetChildren()->Num() % 4, EffectGridPanel->GetChildren()->Num() / 4)
|
||||
[
|
||||
SNew(SCustomInputResource)
|
||||
.CustomInputPanel(this)
|
||||
.PropertyData(Data)
|
||||
.MainInterface(MainWidgetInterface)
|
||||
];
|
||||
@ -537,6 +563,7 @@ void SCustomInputPanel::LoadPanel(const FString& LoadPlace)
|
||||
SNew(SCustomInputResource)
|
||||
.PropertyData(ReloadPropertyData)
|
||||
.MainInterface(MainWidgetInterface)
|
||||
.CustomInputPanel(this)
|
||||
];
|
||||
PropertyData.Add(ReloadPropertyData);
|
||||
}
|
||||
@ -569,5 +596,13 @@ void SCustomInputPanel::AddCustomPreset()
|
||||
|
||||
}
|
||||
|
||||
void SCustomInputPanel::ShowMenu()
|
||||
{
|
||||
FMenuBuilder MenuBuilder(true, CommandList);
|
||||
MenuBuilder.AddMenuEntry(FCustomResourceCommands::Get().Delete);
|
||||
TSharedPtr<SWidget> MenuContent = MenuBuilder.MakeWidget();
|
||||
FSlateApplication::Get().PushMenu(AsShared(), FWidgetPath(), MenuContent.ToSharedRef(), FSlateApplication::Get().GetCursorPos(), FPopupTransitionEffect::ContextMenu);
|
||||
}
|
||||
|
||||
|
||||
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
|
@ -59,9 +59,15 @@ public:
|
||||
bool bIsAssetPanel = false;
|
||||
bool bIsEditMode = false;
|
||||
|
||||
TSharedPtr<FUICommandList> CommandList;
|
||||
|
||||
TSharedPtr<SImage> EditButton;
|
||||
TSharedPtr<SImage> ImportImage;
|
||||
TSharedPtr<STextBlock> ImportText;
|
||||
TArray<FTimelinePropertyData> SelectedProperties;
|
||||
FGuid SelectMenuProperty;
|
||||
|
||||
void ShowMenu();
|
||||
|
||||
|
||||
};
|
||||
|
@ -4,7 +4,9 @@
|
||||
#include "SCustomInputResource.h"
|
||||
|
||||
#include "DefineGlobal.h"
|
||||
#include "SCustomInputPanel.h"
|
||||
#include "SlateOptMacros.h"
|
||||
#include "Commands/CustomResourceCommands.h"
|
||||
#include "Cut5/Utils/Utils.h"
|
||||
|
||||
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
@ -15,6 +17,7 @@ void SCustomInputResource::Construct(const FArguments& InArgs)
|
||||
VideoCapture = InArgs._VideoCapture;
|
||||
OnCheckBoxChecked = InArgs._OnCheckBoxChecked;
|
||||
MainInterface = InArgs._MainInterface;
|
||||
CustomInputPanel = InArgs._CustomInputPanel;
|
||||
ChildSlot
|
||||
[
|
||||
SNew(SBox)
|
||||
@ -59,7 +62,16 @@ void SCustomInputResource::Construct(const FArguments& InArgs)
|
||||
|
||||
FReply SCustomInputResource::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
||||
{
|
||||
return FReply::Handled().DetectDrag(SharedThis(this), EKeys::LeftMouseButton);
|
||||
if (MouseEvent.IsMouseButtonDown(EKeys::LeftMouseButton))
|
||||
{
|
||||
return FReply::Handled().DetectDrag(SharedThis(this), EKeys::LeftMouseButton);
|
||||
}
|
||||
else
|
||||
{
|
||||
CustomInputPanel->SelectMenuProperty = PropertyData.Guid;
|
||||
CustomInputPanel->ShowMenu();
|
||||
}
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
FReply SCustomInputResource::OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
||||
|
@ -20,10 +20,12 @@ public:
|
||||
SLATE_ARGUMENT(cv::VideoCapture, VideoCapture)
|
||||
SLATE_ARGUMENT(ICutMainWidgetInterface*, MainInterface)
|
||||
SLATE_EVENT(FOnCheckBoxChecked, OnCheckBoxChecked)
|
||||
SLATE_ARGUMENT(class SCustomInputPanel*, CustomInputPanel)
|
||||
SLATE_END_ARGS()
|
||||
|
||||
/** Constructs this widget with InArgs */
|
||||
FTimelinePropertyData PropertyData;
|
||||
SCustomInputPanel* CustomInputPanel;
|
||||
void Construct(const FArguments& InArgs);
|
||||
virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
|
||||
virtual FReply OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
|
||||
|
@ -372,7 +372,14 @@ void SCutMainWindow::Construct(const FArguments& InArgs)
|
||||
FShortCutCommands::Register();
|
||||
const FName ContextName = FShortCutCommands::Get().GetContextName();
|
||||
CommandList = MakeShared<FUICommandList>();
|
||||
|
||||
CommandList->MapAction(FShortCutCommands::Get().MicroLeft, FExecuteAction::CreateLambda([this]()
|
||||
{
|
||||
CutTimeline->AddSelectedClipsOffset(-1);
|
||||
}), EUIActionRepeatMode::RepeatEnabled);
|
||||
CommandList->MapAction(FShortCutCommands::Get().MicroRight, FExecuteAction::CreateLambda([this]()
|
||||
{
|
||||
CutTimeline->AddSelectedClipsOffset(1);
|
||||
}), EUIActionRepeatMode::RepeatEnabled);
|
||||
|
||||
CommandList->MapAction(FShortCutCommands::Get().LeftPerFrame, FExecuteAction::CreateLambda([this]()
|
||||
{
|
||||
@ -859,6 +866,7 @@ void SCutMainWindow::OpenProject(const FString& Project)
|
||||
CustomInputPanel->GridPanel->AddSlot(i % 2, i / 2)
|
||||
[
|
||||
SNew(SCustomInputResource)
|
||||
.CustomInputPanel(CustomInputPanel.Get())
|
||||
.PropertyData(ReloadPropertyData)
|
||||
];
|
||||
CustomInputPanel->PropertyData.Add(ReloadPropertyData);
|
||||
@ -926,16 +934,22 @@ void SCutMainWindow::ExportProject(const FString& ExportPath)
|
||||
if (ExportPath.IsEmpty())
|
||||
return;
|
||||
FGlobalData::ExportPath = ExportPath / FGlobalData::CurrentProjectName;
|
||||
|
||||
IDList.Empty();
|
||||
FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*FGlobalData::ExportPath);
|
||||
FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*(FGlobalData::ExportPath / "video"));
|
||||
FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*(FGlobalData::ExportPath / "sound"));
|
||||
FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*(FGlobalData::ExportPath / "psaf"));
|
||||
FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*(FGlobalData::ExportPath / "Video"));
|
||||
FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*(FGlobalData::ExportPath / "Sound"));
|
||||
FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*(FGlobalData::ExportPath / "PSAF"));
|
||||
|
||||
tinyxml2::XMLDocument Document;
|
||||
tinyxml2::XMLElement* RootElement = Document.NewElement("Project");
|
||||
|
||||
RootElement->SetAttribute("Name", TCHAR_TO_UTF8(*FGlobalData::CurrentProjectName));
|
||||
Document.InsertFirstChild(RootElement);
|
||||
|
||||
tinyxml2::XMLDeclaration* decl = Document.NewDeclaration("xml version=\"1.0\"");
|
||||
tinyxml2::XMLNode* XMLVersion = Document.InsertFirstChild(decl);
|
||||
Document.InsertAfterChild(XMLVersion, RootElement);
|
||||
|
||||
|
||||
tinyxml2::XMLElement* Standard = RootElement->InsertNewChildElement("Standard");
|
||||
tinyxml2::XMLElement* File = Standard->InsertNewChildElement("File");
|
||||
File->InsertNewChildElement("Author")->InsertNewText("Sch");
|
||||
@ -966,6 +980,7 @@ void SCutMainWindow::ExportProject(const FString& ExportPath)
|
||||
tinyxml2::XMLElement* PlayerLight = PlayerLightList->InsertNewChildElement("PlayerLight");
|
||||
PlayerLight->InsertNewChildElement("ID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(DeviceID)));
|
||||
PlayerLight->InsertNewChildElement("RoleName")->InsertNewText(TCHAR_TO_UTF8(*TrackData.DeviceTrackGroup->GroupName));
|
||||
IDList.Add(TrackData.Guid, DeviceID);
|
||||
DeviceID++;
|
||||
}
|
||||
default:
|
||||
@ -984,23 +999,27 @@ void SCutMainWindow::ExportProject(const FString& ExportPath)
|
||||
{
|
||||
tinyxml2::XMLElement* RotationSpeaker = RoundSpeakerList->InsertNewChildElement("RotationSpeaker");
|
||||
RotationSpeaker->InsertNewChildElement("ID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(DeviceID)));
|
||||
RotationSpeaker->InsertNewChildElement("RoleName")->InsertNewText(TCHAR_TO_UTF8(*TrackData.DeviceName));
|
||||
RotationSpeaker->InsertNewChildElement("Name")->InsertNewText(TCHAR_TO_UTF8(*TrackData.DeviceName));
|
||||
DeviceID++;
|
||||
IDList.Add(TrackData.Guid, DeviceID);
|
||||
RotatorSpeakerIndex = DeviceID;
|
||||
}
|
||||
break;
|
||||
case ETrackType::LightArrayTrack:
|
||||
{
|
||||
tinyxml2::XMLElement* LightArray = LightArrayList->InsertNewChildElement("GuangZhen");
|
||||
LightArray->InsertNewChildElement("ID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(DeviceID)));
|
||||
LightArray->InsertNewChildElement("RoleName")->InsertNewText(TCHAR_TO_UTF8(*TrackData.DeviceName));
|
||||
LightArray->InsertNewChildElement("Name")->InsertNewText(TCHAR_TO_UTF8(*TrackData.DeviceName));
|
||||
DeviceID++;
|
||||
IDList.Add(TrackData.Guid, DeviceID);
|
||||
LightArrayIndex = DeviceID;
|
||||
}
|
||||
break;
|
||||
case ETrackType::ProjectorTrack:
|
||||
{
|
||||
tinyxml2::XMLElement* Projector = ProjectorList->InsertNewChildElement("Projector");
|
||||
Projector->InsertNewChildElement("ID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(DeviceID)));
|
||||
Projector->InsertNewChildElement("RoleName")->InsertNewText(TCHAR_TO_UTF8(*TrackData.DeviceName));
|
||||
Projector->InsertNewChildElement("Name")->InsertNewText(TCHAR_TO_UTF8(*TrackData.DeviceName));
|
||||
DeviceID++;
|
||||
}
|
||||
break;
|
||||
@ -1008,8 +1027,17 @@ void SCutMainWindow::ExportProject(const FString& ExportPath)
|
||||
{
|
||||
tinyxml2::XMLElement* DMLight = DMLightList->InsertNewChildElement("DMLight");
|
||||
DMLight->InsertNewChildElement("ID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(DeviceID)));
|
||||
DMLight->InsertNewChildElement("RoleName")->InsertNewText(TCHAR_TO_UTF8(*TrackData.DeviceName));
|
||||
DMLight->InsertNewChildElement("Name")->InsertNewText(TCHAR_TO_UTF8(*TrackData.DeviceName));
|
||||
DeviceID++;
|
||||
IDList.Add(TrackData.Guid, DeviceID);
|
||||
}
|
||||
case ETrackType::LightBarTrack:
|
||||
{
|
||||
tinyxml2::XMLElement* LightArray = LightArrayList->InsertNewChildElement("GuangZhen");
|
||||
LightArray->InsertNewChildElement("ID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(DeviceID)));
|
||||
LightArray->InsertNewChildElement("Name")->InsertNewText(TCHAR_TO_UTF8(*TrackData.DeviceName));
|
||||
DeviceID++;
|
||||
IDList.Add(TrackData.Guid, DeviceID);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
@ -1018,7 +1046,9 @@ void SCutMainWindow::ExportProject(const FString& ExportPath)
|
||||
}
|
||||
|
||||
|
||||
tinyxml2::XMLElement* CardList = RootElement->InsertNewChildElement("CardList");
|
||||
int32 CardType = 0;
|
||||
|
||||
tinyxml2::XMLElement* CardList = DeviceList->InsertNewChildElement("CardList");
|
||||
for (int32 i = 0; i < EffectCardsPanel->EffectCardGroups.Num(); i ++)
|
||||
{
|
||||
if (EffectCardsPanel->EffectCardGroups[i].bIsDedicated)
|
||||
@ -1027,35 +1057,88 @@ void SCutMainWindow::ExportProject(const FString& ExportPath)
|
||||
{
|
||||
tinyxml2::XMLElement* Card = CardList->InsertNewChildElement("Card");
|
||||
Card->InsertNewChildElement("ID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].Cards[j].ID)));
|
||||
Card->InsertNewChildElement("Type")->InsertNewText(EffectCardsPanel->EffectCardGroups[i].bIsDedicated ? "0" : "2");
|
||||
Card->InsertNewChildElement("Times");
|
||||
Card->InsertNewChildElement("Step");
|
||||
int32 TypeID = 0;
|
||||
if (EffectCardsPanel->EffectCardGroups[i].Cards[j].JumpStepCurtains.Guid.IsValid())
|
||||
{
|
||||
TypeID = 1;
|
||||
}
|
||||
Card->InsertNewChildElement("Type")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(TypeID)));
|
||||
Card->InsertNewChildElement("Times")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(-1)));
|
||||
|
||||
int32 ToStepID = 0;
|
||||
if (TypeID == 1)
|
||||
{
|
||||
for (int32 k = 0; i < CurtainPanel->Groups.Num(); k++)
|
||||
{
|
||||
for (FCurtain& Curtain : CurtainPanel->Groups[k].Curtains)
|
||||
{
|
||||
if (Curtain.CurtainUUID == EffectCardsPanel->EffectCardGroups[i].Cards[j].JumpStepCurtains.Guid)
|
||||
{
|
||||
ToStepID = Curtain.Step + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Card->InsertNewChildElement("Step")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(ToStepID)));
|
||||
Card->InsertNewChildElement("SpecialEffectID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].Cards[j].ID)));
|
||||
Card->InsertNewChildElement("SerialNumberList");
|
||||
Card->InsertNewChildElement("SerialNumberList")->InsertNewChildElement("SerialNumber")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].Cards[j].ID)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int32 j = 0; j < EffectCardsPanel->EffectCardGroups[i].Cards.Num(); j++)
|
||||
tinyxml2::XMLElement* Card = CardList->InsertNewChildElement("Card");
|
||||
|
||||
|
||||
Card->InsertNewChildElement("ID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].ID)));
|
||||
|
||||
int32 TypeID = 2;
|
||||
if (EffectCardsPanel->EffectCardGroups[i].JumpStepCurtains.Guid.IsValid())
|
||||
{
|
||||
tinyxml2::XMLElement* Card = CardList->InsertNewChildElement("Card");
|
||||
Card->InsertNewChildElement("ID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].ID)));
|
||||
Card->InsertNewChildElement("Type")->InsertNewText(EffectCardsPanel->EffectCardGroups[0].bIsDedicated ? "0" : "2");
|
||||
Card->InsertNewChildElement("Times");
|
||||
Card->InsertNewChildElement("Step");
|
||||
Card->InsertNewChildElement("SpecialEffectID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].ID)));
|
||||
tinyxml2::XMLElement* SerialNumberList = Card->InsertNewChildElement("SerialNumberList");
|
||||
for (int32 k = 0; k < EffectCardsPanel->EffectCardGroups[i].Cards.Num(); k++)
|
||||
TypeID = 3;
|
||||
}
|
||||
|
||||
Card->InsertNewChildElement("Type")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(TypeID)));
|
||||
Card->InsertNewChildElement("Times")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(-1)));
|
||||
|
||||
|
||||
int32 ToStepID = 0;
|
||||
if (TypeID == 3)
|
||||
{
|
||||
for (int32 k = 0; i < CurtainPanel->Groups.Num(); k++)
|
||||
{
|
||||
SerialNumberList->InsertNewChildElement("SerialNumber")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].Cards[k].ID)));
|
||||
for (FCurtain& Curtain : CurtainPanel->Groups[k].Curtains)
|
||||
{
|
||||
if (Curtain.CurtainUUID == EffectCardsPanel->EffectCardGroups[i].JumpStepCurtains.Guid)
|
||||
{
|
||||
ToStepID = Curtain.Step + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Card->InsertNewChildElement("Step")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(ToStepID)));
|
||||
Card->InsertNewChildElement("SpecialEffectID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].ID)));
|
||||
tinyxml2::XMLElement* SerialNumberList = Card->InsertNewChildElement("SerialNumberList");
|
||||
for (int32 k = 0; k < EffectCardsPanel->EffectCardGroups[i].Cards.Num(); k++)
|
||||
{
|
||||
SerialNumberList->InsertNewChildElement("SerialNumber")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].Cards[k].ID)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// KeyBoard
|
||||
tinyxml2::XMLElement* Keyboard = RootElement->InsertNewChildElement("KeyBoard");
|
||||
{
|
||||
tinyxml2::XMLElement* KeyCode = Keyboard->InsertNewChildElement("KeyCode");
|
||||
KeyCode->InsertNewChildElement("CTRL")->InsertNewText("");
|
||||
KeyCode->InsertNewChildElement("SHIFT")->InsertNewText("");
|
||||
KeyCode->InsertNewChildElement("ALT")->InsertNewText("");
|
||||
KeyCode->InsertNewChildElement("KEY")->InsertNewText("");
|
||||
KeyCode->InsertNewChildElement("SpecialEffectID")->InsertNewText("");
|
||||
}
|
||||
}
|
||||
// ProcessList
|
||||
tinyxml2::XMLElement* ProcessList = RootElement->InsertNewChildElement("ProcessList");
|
||||
@ -1291,7 +1374,7 @@ void SCutMainWindow::AddNewCustomPreset(const FString& Name, const FPresetsCusto
|
||||
NewPropertyData.PresetsCustomData = CustomData;
|
||||
NewPropertyData.Name = Name;
|
||||
|
||||
TSharedPtr<SCustomInputResource> CustomInputResource = SNew(SCustomInputResource).PropertyData(NewPropertyData);
|
||||
TSharedPtr<SCustomInputResource> CustomInputResource = SNew(SCustomInputResource).PropertyData(NewPropertyData).CustomInputPanel(CustomInputPanel.Get());
|
||||
CustomInputPanel->GridPanel->AddSlot(CustomInputPanel->GridPanel->GetChildren()->Num() % 2, CustomInputPanel->GridPanel->GetChildren()->Num() / 2)
|
||||
[
|
||||
CustomInputResource.ToSharedRef()
|
||||
@ -1342,21 +1425,35 @@ tinyxml2::XMLElement* SCutMainWindow::GetDeviceElement(tinyxml2::XMLElement* Par
|
||||
// DMLightList
|
||||
tinyxml2::XMLElement* DMLightList = Light->InsertNewChildElement("DMLightList");
|
||||
{
|
||||
|
||||
int32 j = 0;
|
||||
for (int32 i = 0; i < CutTimeline->TrackGroupInstances.Num(); i++)
|
||||
{
|
||||
const FTrackData& TrackData = StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData;
|
||||
if (TrackData.TrackType == ETrackType::SpotLightTrack)
|
||||
{
|
||||
tinyxml2::XMLElement* Event_List = DMLightList->InsertNewChildElement(TCHAR_TO_UTF8(*FString::Printf(TEXT("DMLight(%d)"), j)))->InsertNewChildElement("Event_List");
|
||||
|
||||
|
||||
tinyxml2::XMLElement* DMLight = DMLightList->InsertNewChildElement(TCHAR_TO_UTF8(*FString::Printf(TEXT("DMLight"))));
|
||||
DMLight->SetAttribute("ID", TCHAR_TO_UTF8(*FString::FromInt(GetTrackID(TrackData.DeviceTrack.Guid))));
|
||||
|
||||
tinyxml2::XMLElement* Event_List = DMLight->InsertNewChildElement("Event_List");
|
||||
int32 Count = 0;
|
||||
for (int32 k = 0; k < TrackData.ClipData.Num(); k++)
|
||||
{
|
||||
const FClipData& TempClipData = TrackData.ClipData[k];
|
||||
Event_List->InsertNewChildElement("Value")->InsertNewText("1");
|
||||
Event_List->InsertNewChildElement("Timecode")->InsertNewText(TCHAR_TO_UTF8(*FString::Printf(TEXT("%ls"), *FUtils::GetMsFromString(FGlobalData::GetTimeData(TempClipData.ClipStartFrame)))));
|
||||
Event_List->InsertNewChildElement("Value")->InsertNewText("0");
|
||||
Event_List->InsertNewChildElement("Timecode")->InsertNewText(TCHAR_TO_UTF8(*FString::Printf(TEXT("%ls"), *FUtils::GetMsFromString(FGlobalData::GetTimeData(TempClipData.ClipEndFrame)))));
|
||||
tinyxml2::XMLElement* Event1 = Event_List->InsertNewChildElement("Event");
|
||||
Event1->InsertNewChildElement("Value")->InsertNewText("1");
|
||||
Event1->InsertNewChildElement("Timecode")->InsertNewText(TCHAR_TO_UTF8(*FString::Printf(TEXT("%ls"), *FUtils::GetMsFromString(FGlobalData::GetTimeData(TempClipData.ClipStartFrame)))));
|
||||
|
||||
tinyxml2::XMLElement* Event2 = Event_List->InsertNewChildElement("Event");
|
||||
Event2->InsertNewChildElement("Value")->InsertNewText("0");
|
||||
Event2->InsertNewChildElement("Timecode")->InsertNewText(TCHAR_TO_UTF8(*FString::Printf(TEXT("%ls"), *FUtils::GetMsFromString(FGlobalData::GetTimeData(TempClipData.ClipEndFrame)))));
|
||||
Count++;
|
||||
}
|
||||
if (Count == 0)
|
||||
{
|
||||
Event_List->InsertNewText("");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1369,8 +1466,14 @@ tinyxml2::XMLElement* SCutMainWindow::GetDeviceElement(tinyxml2::XMLElement* Par
|
||||
const FTrackData& TrackData = StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData;
|
||||
if (TrackData.TrackType == ETrackType::AtomSphereLightTrack)
|
||||
{
|
||||
tinyxml2::XMLElement* PlayerLight = PlayerLightList->InsertNewChildElement(TCHAR_TO_UTF8(*FString::Printf(TEXT("PlayerLight(%d)"), j)));
|
||||
tinyxml2::XMLElement* PlayerLight = PlayerLightList->InsertNewChildElement(TCHAR_TO_UTF8(*FString::Printf(TEXT("PlayerLight"))));
|
||||
PlayerLight->SetAttribute("ID", TCHAR_TO_UTF8(*FString::FromInt(GetTrackID(TrackData.DeviceTrack.Guid))));
|
||||
|
||||
tinyxml2::XMLElement* SpeicalEffect = PlayerLight->InsertNewChildElement("Special_Effects_List");
|
||||
if (TrackData.ClipData.Num() == 0)
|
||||
{
|
||||
SpeicalEffect->InsertNewText("");
|
||||
}
|
||||
for (int32 k = 0; k < TrackData.ClipData.Num(); k++)
|
||||
{
|
||||
|
||||
@ -1406,48 +1509,67 @@ tinyxml2::XMLElement* SCutMainWindow::GetDeviceElement(tinyxml2::XMLElement* Par
|
||||
}
|
||||
tinyxml2::XMLElement* GuangZhenList = Light->InsertNewChildElement("GuangZhenList");
|
||||
{
|
||||
auto GuangZhenSpecialEffectList = GuangZhenList->InsertNewChildElement("SpecialEffectList");
|
||||
for (int32 i = 0; i < CutTimeline->TrackGroupInstances.Num(); i++)
|
||||
|
||||
for (int32 k = 0; k < CutTimeline->TrackGroupInstances.Num(); k++)
|
||||
{
|
||||
if (StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData.TrackType == ETrackType::LightArrayTrack)
|
||||
int32 Index = 0;
|
||||
const FTrackData& TrackData = StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[k].Head)->TrackData;
|
||||
if (TrackData.TrackType == ETrackType::LightArrayTrack || TrackData.TrackType == ETrackType::LightBarTrack)
|
||||
{
|
||||
TArray<FEncodeVideoInfo> EncodeVideoInfos = FUtils::ExportPsaf(StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData, *(FGlobalData::ExportPath / "psaf"));
|
||||
for (int32 j = 0; j < EncodeVideoInfos.Num(); j++)
|
||||
auto GuangZhen = GuangZhenList->InsertNewChildElement("GuangZhen");
|
||||
GuangZhen->SetAttribute("ID", TCHAR_TO_UTF8(*FString::FromInt(GetTrackID(TrackData.DeviceTrack.Guid))));
|
||||
|
||||
int32 Count = 0;
|
||||
auto GuangZhenSpecialEffectList = GuangZhen->InsertNewChildElement("SpecialEffectList");
|
||||
for (int32 i = 0; i < CutTimeline->TrackGroupInstances.Num(); i++)
|
||||
{
|
||||
auto SpeicalEffect = GuangZhenSpecialEffectList->InsertNewChildElement("SpeicalEffect");
|
||||
if (StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData.TrackType == ETrackType::LightArrayTrack)
|
||||
{
|
||||
auto SpeicalEffectTimeCode = SpeicalEffect->InsertNewChildElement("TimeCode");
|
||||
TArray<FEncodeVideoInfo> EncodeVideoInfos = FUtils::ExportPsaf(StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData, *(FGlobalData::ExportPath / "PSAF"));
|
||||
for (int32 j = 0; j < EncodeVideoInfos.Num(); j++)
|
||||
{
|
||||
SpeicalEffectTimeCode->InsertNewText(TCHAR_TO_UTF8(*FUtils::GetMsFromString(EncodeVideoInfos[j].EncodedVideoTimeCode)));
|
||||
}
|
||||
auto SpeicalEffectURL = SpeicalEffect->InsertNewChildElement("URL");
|
||||
{
|
||||
SpeicalEffectURL->InsertNewText(TCHAR_TO_UTF8(*EncodeVideoInfos[j].EncodedVideoName));
|
||||
}
|
||||
auto SpeicalEffectLoop = SpeicalEffect->InsertNewChildElement("Loop");
|
||||
{
|
||||
SpeicalEffectLoop->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(0)));
|
||||
}
|
||||
auto SpeicalEffectMode = SpeicalEffect->InsertNewChildElement("Mode");
|
||||
{
|
||||
SpeicalEffectMode->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(0)));
|
||||
auto SpeicalEffect = GuangZhenSpecialEffectList->InsertNewChildElement("SpeicalEffect");
|
||||
{
|
||||
auto SpeicalEffectTimeCode = SpeicalEffect->InsertNewChildElement("TimeCode");
|
||||
{
|
||||
SpeicalEffectTimeCode->InsertNewText(TCHAR_TO_UTF8(*FUtils::GetMsFromString(EncodeVideoInfos[j].EncodedVideoTimeCode)));
|
||||
}
|
||||
auto SpeicalEffectURL = SpeicalEffect->InsertNewChildElement("URL");
|
||||
{
|
||||
SpeicalEffectURL->InsertNewText(TCHAR_TO_UTF8(*EncodeVideoInfos[j].EncodedVideoName));
|
||||
}
|
||||
auto SpeicalEffectLoop = SpeicalEffect->InsertNewChildElement("Loop");
|
||||
{
|
||||
SpeicalEffectLoop->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(0)));
|
||||
}
|
||||
auto SpeicalEffectMode = SpeicalEffect->InsertNewChildElement("Mode");
|
||||
{
|
||||
SpeicalEffectMode->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(0)));
|
||||
}
|
||||
}
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Count == 0)
|
||||
{
|
||||
GuangZhenSpecialEffectList->InsertNewText("");
|
||||
}
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
tinyxml2::XMLElement* RoomLight = Light->InsertNewChildElement("RoomLight");
|
||||
{
|
||||
|
||||
RoomLight->InsertNewText("0");
|
||||
}
|
||||
tinyxml2::XMLElement* JLight = Light->InsertNewChildElement("JLight");
|
||||
{
|
||||
|
||||
JLight->InsertNewText("0");
|
||||
}
|
||||
tinyxml2::XMLElement* Incense_Machine = Light->InsertNewChildElement("Incense_Machine");
|
||||
{
|
||||
|
||||
Incense_Machine->InsertNewText("0");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1479,7 +1601,29 @@ tinyxml2::XMLElement* SCutMainWindow::GetVideoElement(tinyxml2::XMLElement* Pare
|
||||
{
|
||||
ProjectorID->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(TempProjectorID)));
|
||||
}
|
||||
|
||||
tinyxml2::XMLElement* VolumeEventList = Video->InsertNewChildElement("VolumeEventList");
|
||||
{
|
||||
tinyxml2::XMLElement* VolumeEvent = VolumeEventList->InsertNewChildElement("VolumeEvent");
|
||||
{
|
||||
tinyxml2::XMLElement* VolumeEventTimeCode = VolumeEvent->InsertNewChildElement("TimeCode");
|
||||
tinyxml2::XMLElement* VolumeEventValue = VolumeEvent->InsertNewChildElement("Value");
|
||||
|
||||
if (EncodeVideoInfo.TrackData.IsMute)
|
||||
{
|
||||
VolumeEventTimeCode->InsertNewText("0");
|
||||
VolumeEventValue->InsertNewText("0");
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Dynamic Volume
|
||||
VolumeEventTimeCode->InsertNewText("0");
|
||||
VolumeEventValue->InsertNewText("100");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
tinyxml2::XMLElement* ProjectorEventList = Video->InsertNewChildElement("ProjectorEventList");
|
||||
{
|
||||
@ -1519,6 +1663,7 @@ tinyxml2::XMLElement* SCutMainWindow::GetVideoElement(tinyxml2::XMLElement* Pare
|
||||
Value->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(ShowProjector)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -1534,7 +1679,9 @@ tinyxml2::XMLElement* SCutMainWindow::GetSoundElement(tinyxml2::XMLElement* Pare
|
||||
{
|
||||
tinyxml2::XMLElement* Sound = Parent->InsertNewChildElement("Sound");
|
||||
{
|
||||
Sound->InsertNewChildElement("RotationSpeakerID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(RotatorSpeakerIndex)));
|
||||
Sound->InsertNewChildElement("URL")->InsertNewText(TCHAR_TO_UTF8(*(FPaths::GetBaseFilename(EncodeVideoInfo.EncodedVideoName) + TEXT(".mp3"))));
|
||||
|
||||
Sound->InsertNewChildElement("Loop")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(0)));
|
||||
Sound->InsertNewChildElement("Mode")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(0)));
|
||||
Sound->InsertNewChildElement("Round")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(0)));
|
||||
@ -1545,6 +1692,30 @@ tinyxml2::XMLElement* SCutMainWindow::GetSoundElement(tinyxml2::XMLElement* Pare
|
||||
{
|
||||
tinyxml2::XMLElement* VolumeEventTimeCode = VolumeEvent->InsertNewChildElement("TimeCode");
|
||||
tinyxml2::XMLElement* VolumeEventValue = VolumeEvent->InsertNewChildElement("Value");
|
||||
|
||||
if (EncodeVideoInfo.TrackData.IsMute)
|
||||
{
|
||||
VolumeEventTimeCode->InsertNewText("0");
|
||||
VolumeEventValue->InsertNewText("0");
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Dynamic Volume
|
||||
VolumeEventTimeCode->InsertNewText("0");
|
||||
VolumeEventValue->InsertNewText("100");
|
||||
}
|
||||
}
|
||||
}
|
||||
tinyxml2::XMLElement* RotationSpeakerEventList = Sound->InsertNewChildElement("RotationSpeakerEventList");
|
||||
{
|
||||
tinyxml2::XMLElement* RotationSpeakerEvent = RotationSpeakerEventList->InsertNewChildElement("RotationSpeakerEvent");
|
||||
{
|
||||
tinyxml2::XMLElement* RotationSpeakerEventTimeCode = RotationSpeakerEvent->InsertNewChildElement("TimeCode");
|
||||
tinyxml2::XMLElement* RotationSpeakerEventValue = RotationSpeakerEvent->InsertNewChildElement("Value");
|
||||
|
||||
|
||||
RotationSpeakerEventTimeCode->InsertNewText("0");
|
||||
RotationSpeakerEventValue->InsertNewText("0");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1554,20 +1725,26 @@ tinyxml2::XMLElement* SCutMainWindow::GetSoundElement(tinyxml2::XMLElement* Pare
|
||||
tinyxml2::XMLElement* SCutMainWindow::GetVideoListElement(tinyxml2::XMLElement* Parent)
|
||||
{
|
||||
tinyxml2::XMLElement* VideoList = Parent->InsertNewChildElement("VideoList");
|
||||
int32 Count = 0;
|
||||
for (int32 i = 0; i < CutTimeline->TrackGroupInstances.Num(); i++)
|
||||
{
|
||||
if (StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData.TrackType == ETrackType::VideoTrack)
|
||||
{
|
||||
FString Filename = FGuid::NewGuid().ToString();
|
||||
FString NewExportFilePath = FGlobalData::ExportPath / "video" / Filename;
|
||||
FString NewExportFilePath = FGlobalData::ExportPath / "Video" / Filename;
|
||||
TArray<FEncodeVideoInfo> EncodeVideoInfos = FUtils::TrackEncodeVideo(StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData, NewExportFilePath);
|
||||
for (FEncodeVideoInfo EncodeVideoInfo : EncodeVideoInfos)
|
||||
{
|
||||
GetVideoElement(VideoList, EncodeVideoInfo);
|
||||
Count++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (Count == 0)
|
||||
{
|
||||
VideoList->InsertNewText("");
|
||||
}
|
||||
return VideoList;
|
||||
}
|
||||
|
||||
@ -1575,20 +1752,27 @@ tinyxml2::XMLElement* SCutMainWindow::GetSoundListElement(tinyxml2::XMLElement*
|
||||
{
|
||||
tinyxml2::XMLElement* AudioList = Parent->InsertNewChildElement("SoundList");
|
||||
{
|
||||
int32 Count = 0;
|
||||
for (int32 i = 0; i < CutTimeline->TrackGroupInstances.Num(); i++)
|
||||
{
|
||||
if (StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData.TrackType == ETrackType::AudioTrack ||
|
||||
StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData.TrackType == ETrackType::AudioTrackR)
|
||||
{
|
||||
FString Filename = FGuid::NewGuid().ToString();
|
||||
FString NewExportFilePath = FGlobalData::ExportPath / "sound" / Filename;
|
||||
FString NewExportFilePath = FGlobalData::ExportPath / "Sound" / Filename;
|
||||
TArray<FEncodeVideoInfo> EncodeVideoInfos = FUtils::TrackEncodeAudio(StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData, NewExportFilePath);
|
||||
for (FEncodeVideoInfo EncodeVideoInfo : EncodeVideoInfos)
|
||||
{
|
||||
GetSoundElement(AudioList, EncodeVideoInfo);
|
||||
Count++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (Count == 0)
|
||||
{
|
||||
AudioList->InsertNewText("");
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -1609,9 +1793,9 @@ tinyxml2::XMLElement* SCutMainWindow::GetProcessB(tinyxml2::XMLElement* Parent,
|
||||
{
|
||||
tinyxml2::XMLElement* ProcessB = Parent->InsertNewChildElement("ProcessB");
|
||||
ProcessB->SetAttribute("Name", TCHAR_TO_UTF8(*Curtain->CurtainName));
|
||||
tinyxml2::XMLElement* ProcessID = ProcessB->InsertNewChildElement("ID");
|
||||
tinyxml2::XMLElement* AutoNext = ProcessB->InsertNewChildElement("AutoNext");
|
||||
tinyxml2::XMLElement* TimeLength = ProcessB->InsertNewChildElement("TimeLength");
|
||||
ProcessB->InsertNewChildElement("ID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(Curtain->Step)));
|
||||
ProcessB->InsertNewChildElement("AutoNext")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(0)));
|
||||
ProcessB->InsertNewChildElement("TimeLength")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(-1)));
|
||||
|
||||
GetSoundListElement(ProcessB);
|
||||
ProcessB->InsertEndChild(GetDeviceElement(ProcessB));
|
||||
@ -1620,15 +1804,49 @@ tinyxml2::XMLElement* SCutMainWindow::GetProcessB(tinyxml2::XMLElement* Parent,
|
||||
// 非必须项
|
||||
tinyxml2::XMLElement* Identity_SpecialEffects = ProcessB->InsertNewChildElement("Identity_SpecialEffects");
|
||||
{
|
||||
|
||||
Identity_SpecialEffects->InsertNewText("");
|
||||
}
|
||||
tinyxml2::XMLElement* IsGlobal = ProcessB->InsertNewChildElement("IsGlobal");
|
||||
{
|
||||
|
||||
IsGlobal->InsertNewText("1");
|
||||
}
|
||||
tinyxml2::XMLElement* State = ProcessB->InsertNewChildElement("State");
|
||||
{
|
||||
|
||||
State->InsertNewText("");
|
||||
}
|
||||
tinyxml2::XMLElement* EnableCard = ProcessB->InsertNewChildElement("EnableCard");
|
||||
{
|
||||
int32 Count = 0;
|
||||
for (int32 i = 0; i < EffectCardsPanel->EffectCardGroups.Num(); i++)
|
||||
{
|
||||
|
||||
if (!EffectCardsPanel->EffectCardGroups[i].bIsDedicated)
|
||||
{
|
||||
if (EffectCardsPanel->EffectCardGroups[i].UsedCurtains.Contains(Curtain->CurtainUUID))
|
||||
{
|
||||
tinyxml2::XMLElement* SerialNumber = EnableCard->InsertNewChildElement("SerialNumber");
|
||||
SerialNumber->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].ID)));
|
||||
Count++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int32 j = 0 ; j < EffectCardsPanel->EffectCardGroups[i].Cards.Num(); j++)
|
||||
{
|
||||
if (EffectCardsPanel->EffectCardGroups[i].Cards[j].UsedCurtains.Contains(Curtain->CurtainUUID))
|
||||
{
|
||||
tinyxml2::XMLElement* SerialNumber = EnableCard->InsertNewChildElement("SerialNumber");
|
||||
SerialNumber->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].Cards[j].ID)));
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (Count == 0)
|
||||
{
|
||||
EnableCard->InsertNewText("");
|
||||
}
|
||||
|
||||
}
|
||||
return ProcessB;
|
||||
}
|
||||
@ -1641,12 +1859,8 @@ tinyxml2::XMLElement* SCutMainWindow::GetSpecialEffectList(tinyxml2::XMLElement*
|
||||
{
|
||||
if (!EffectCardsPanel->EffectCardGroups[i].bIsDedicated)
|
||||
{
|
||||
if (EffectCardsPanel->EffectCardGroups[i].bIsDedicated == false)
|
||||
{
|
||||
const FString Name = FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName, TEXT("FX"), EffectCardsPanel->EffectCardGroups[i].GroupName + TEXT(".bin"));
|
||||
OpenTimeline(Name, true, true);
|
||||
CurrentSelectedPropertiesInterfaceGuid = EffectCardsPanel->EffectCardGroups[i].Guid;
|
||||
}
|
||||
OpenTimeline(FUtils::GroupFullPath(EffectCardsPanel->EffectCardGroups[i].Guid.ToString()), true, true);
|
||||
CurrentSelectedPropertiesInterfaceGuid = EffectCardsPanel->EffectCardGroups[i].Guid;
|
||||
GetSpecialEffectGroup(SpecialEffectsList, &EffectCardsPanel->EffectCardGroups[i]);
|
||||
SpecialEffectID++;
|
||||
continue;
|
||||
@ -1661,6 +1875,11 @@ tinyxml2::XMLElement* SCutMainWindow::GetSpecialEffectList(tinyxml2::XMLElement*
|
||||
|
||||
SpecialEffectID++;
|
||||
}
|
||||
|
||||
if (SpecialEffectID == 0)
|
||||
{
|
||||
SpecialEffectsList->InsertNewText("");
|
||||
}
|
||||
return SpecialEffectsList;
|
||||
}
|
||||
|
||||
@ -1675,6 +1894,7 @@ tinyxml2::XMLElement* SCutMainWindow::GetSpecialEffectGroup(tinyxml2::XMLElement
|
||||
ID->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(Group->ID)));
|
||||
}
|
||||
tinyxml2::XMLElement* AutoNext = Effect->InsertNewChildElement("AutoNext");
|
||||
AutoNext->InsertNewText("0");
|
||||
GetSoundListElement(Effect);
|
||||
GetDeviceElement(Effect);
|
||||
GetVideoListElement(Effect);
|
||||
@ -1686,7 +1906,7 @@ tinyxml2::XMLElement* SCutMainWindow::GetSpecialEffectGroup(tinyxml2::XMLElement
|
||||
}
|
||||
tinyxml2::XMLElement* State = Effect->InsertNewChildElement("State");
|
||||
{
|
||||
|
||||
State->InsertNewText("0");
|
||||
}
|
||||
return Effect;
|
||||
}
|
||||
@ -1701,25 +1921,9 @@ tinyxml2::XMLElement* SCutMainWindow::GetSpecialEffect(tinyxml2::XMLElement* Par
|
||||
{
|
||||
ID->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(Effect->ID)));
|
||||
}
|
||||
|
||||
int32 CardType = 0;
|
||||
if (Effect->JumpStepCurtains.Guid.IsValid())
|
||||
{
|
||||
CardType = 1;
|
||||
}
|
||||
|
||||
Effectxml->InsertNewChildElement("Type")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(CardType)));
|
||||
Effectxml->InsertNewChildElement("Times")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(-1)));
|
||||
int32 Step = 0;
|
||||
|
||||
for (int32 i = 0; i < CurtainPanel->Groups.Num(); i++)
|
||||
{
|
||||
|
||||
}
|
||||
Effectxml->InsertNewChildElement("Step")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(Step)));
|
||||
|
||||
|
||||
tinyxml2::XMLElement* AutoNext = Effectxml->InsertNewChildElement("AutoNext");
|
||||
AutoNext->InsertNewText("0");
|
||||
GetSoundListElement(Effectxml);
|
||||
GetDeviceElement(Effectxml);
|
||||
GetVideoListElement(Effectxml);
|
||||
@ -1731,10 +1935,17 @@ tinyxml2::XMLElement* SCutMainWindow::GetSpecialEffect(tinyxml2::XMLElement* Par
|
||||
}
|
||||
tinyxml2::XMLElement* State = Effectxml->InsertNewChildElement("State");
|
||||
{
|
||||
|
||||
State->InsertNewText("0");
|
||||
}
|
||||
return Effectxml;
|
||||
}
|
||||
|
||||
int32 SCutMainWindow::GetTrackID(FGuid Guid) const
|
||||
{
|
||||
const int32* Index = IDList.Find(Guid);
|
||||
const int32 NewIndex = Index != nullptr ? *Index : -1;
|
||||
return NewIndex;
|
||||
}
|
||||
|
||||
|
||||
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
|
@ -108,6 +108,12 @@ public:
|
||||
tinyxml2::XMLElement* GetSpecialEffectList(tinyxml2::XMLElement* Parent);
|
||||
tinyxml2::XMLElement* GetSpecialEffectGroup(tinyxml2::XMLElement* Parent, FEffectCardGroup* Group);
|
||||
tinyxml2::XMLElement* GetSpecialEffect(tinyxml2::XMLElement* Parent, FEffectCardProperty* Effect);
|
||||
|
||||
int32 RotatorSpeakerIndex = 0;
|
||||
int32 LightArrayIndex = 0;
|
||||
|
||||
TMap<FGuid, int32> IDList = {};
|
||||
int32 GetTrackID(FGuid Guid) const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -188,7 +188,7 @@ void SCutTimeline::Construct(const FArguments& InArgs)
|
||||
.OnValueChanged_Lambda([this](float ChangedValue)
|
||||
{
|
||||
FGlobalData::DefaultTimeTickSpace = FMath::GetMappedRangeValueClamped(FVector2D(0, 1.0), FVector2D(GetCachedGeometry().GetLocalSize().X / FGlobalData::TrackLength, 14), ChangedValue);
|
||||
|
||||
UpdateCursorPosition(GetCursorPosition());
|
||||
RenderGroup();
|
||||
})
|
||||
]
|
||||
@ -218,7 +218,7 @@ void SCutTimeline::Construct(const FArguments& InArgs)
|
||||
[
|
||||
SNew(SBox)
|
||||
.WidthOverride(10000)
|
||||
.HeightOverride(25)
|
||||
.HeightOverride(40)
|
||||
// 刻度补差值
|
||||
]
|
||||
+ SVerticalBox::Slot()
|
||||
@ -242,7 +242,7 @@ void SCutTimeline::Construct(const FArguments& InArgs)
|
||||
[
|
||||
SNew(SBox)
|
||||
.WidthOverride(10000)
|
||||
.HeightOverride(25)
|
||||
.HeightOverride(40)
|
||||
// 刻度补差值
|
||||
]
|
||||
+ SVerticalBox::Slot()
|
||||
@ -266,7 +266,7 @@ void SCutTimeline::Construct(const FArguments& InArgs)
|
||||
[
|
||||
SAssignNew(TimelineTickBox, SBox)
|
||||
.WidthOverride(FGlobalData::TrackLength * FGlobalData::DefaultTimeTickSpace)
|
||||
.MaxDesiredHeight(60)
|
||||
.HeightOverride(40)
|
||||
[
|
||||
SAssignNew(TickScrollBox, SScrollBox)
|
||||
.ScrollBarVisibility(EVisibility::Hidden)
|
||||
@ -790,6 +790,69 @@ void SCutTimeline::AddNewDeviceToGroup(FString GroupName, FDeviceTrack DeviceTra
|
||||
{
|
||||
MainWidgetInterface->OnAddNewTrack(ETrackType::PlayerTrack);
|
||||
}
|
||||
}
|
||||
|
||||
void SCutTimeline::AddSelectedClipsOffset(int32 FrameOffset)
|
||||
{
|
||||
TArray<FClipData*> NewSelectedClipData;
|
||||
for (int32 i = 0; i < TrackGroupInstances.Num(); i++)
|
||||
{
|
||||
for (FClipData& TempClipData : StaticCastSharedPtr<STrackHead>(TrackGroupInstances[i].Head)->TrackData.ClipData)
|
||||
{
|
||||
if (SelectedClips.Contains(TempClipData.ClipGuid))
|
||||
{
|
||||
NewSelectedClipData.Add(&TempClipData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32 MinFrame = FGlobalData::TrackLength;
|
||||
for (FClipData* ClipData : NewSelectedClipData)
|
||||
{
|
||||
if (ClipData->ClipStartFrame < MinFrame)
|
||||
{
|
||||
MinFrame = ClipData->ClipStartFrame;
|
||||
}
|
||||
}
|
||||
|
||||
int32 MaxFrame = 0;
|
||||
for (FClipData* ClipData : NewSelectedClipData)
|
||||
{
|
||||
if (ClipData->ClipEndFrame > MaxFrame)
|
||||
{
|
||||
MaxFrame = ClipData->ClipEndFrame;
|
||||
}
|
||||
}
|
||||
|
||||
if (FrameOffset > 0)
|
||||
{
|
||||
if (MinFrame >= 0 && MaxFrame < FGlobalData::TrackLength)
|
||||
{
|
||||
for (FClipData* ClipData : NewSelectedClipData)
|
||||
{
|
||||
ClipData->ClipStartFrame += FrameOffset;
|
||||
ClipData->ClipEndFrame += FrameOffset;
|
||||
}
|
||||
RenderGroup();
|
||||
}
|
||||
}
|
||||
else if (FrameOffset < 0)
|
||||
{
|
||||
if (MinFrame > 0 && MaxFrame < FGlobalData::TrackLength)
|
||||
{
|
||||
for (FClipData* ClipData : NewSelectedClipData)
|
||||
{
|
||||
ClipData->ClipStartFrame += FrameOffset;
|
||||
ClipData->ClipEndFrame += FrameOffset;
|
||||
}
|
||||
RenderGroup();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
|
@ -134,6 +134,9 @@ public:
|
||||
TArray<FVector2D> RenderBoxPos {{}, {}};
|
||||
|
||||
bool bNeedShowPanel = false;
|
||||
|
||||
|
||||
void AddSelectedClipsOffset(int32 FrameOffset);
|
||||
};
|
||||
|
||||
|
||||
|
@ -19,9 +19,12 @@
|
||||
#include "DragDropOperator/DragDropOperator.h"
|
||||
#include "Engine/Engine.h"
|
||||
#include "Engine/Texture2D.h"
|
||||
#include "MicroWidgets/SNewProjectTips.h"
|
||||
#include "Presets/SClipCursor.h"
|
||||
#include "Rendering/DrawElementPayloads.h"
|
||||
#include "Slate/Private/Framework/Application/Menu.h"
|
||||
#include "Widgets/Input/SSpinBox.h"
|
||||
#include "Widgets/Layout/SSpacer.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@ -49,7 +52,7 @@ FReply STimelineClip::OnBorderMouseButtonDown(const FGeometry& Geometry, const F
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (MainWidgetInterface->GetSelectedMode() == ESelectMode::CutMode)
|
||||
{
|
||||
Body->SelectedClipFrame = (Geometry.AbsoluteToLocal(PointerEvent.GetScreenSpacePosition()).X) / FGlobalData::DefaultTimeTickSpace;
|
||||
@ -58,11 +61,15 @@ FReply STimelineClip::OnBorderMouseButtonDown(const FGeometry& Geometry, const F
|
||||
}
|
||||
|
||||
|
||||
MainWidgetInterface->GetCutTimeline()->SelectedClips.AddUnique(ClipData->ClipGuid);
|
||||
MainWidgetInterface->UpdateProperties(nullptr);
|
||||
MainWidgetInterface->UpdateProperties(this);
|
||||
|
||||
LocalPos = Geometry.AbsoluteToLocal(PointerEvent.GetScreenSpacePosition());
|
||||
const float DragOffset = MainWidgetInterface->GetCutTimeline()->GetCachedGeometry().AbsoluteToLocal(PointerEvent.GetScreenSpacePosition()).X;
|
||||
if (LocalPos.X <= 10)
|
||||
{
|
||||
if (ClipData->bCanDrag && !MainWidgetInterface->GetCutTimeline()->SelectedClips.Contains(ClipData->ClipGuid))
|
||||
if (ClipData->bCanDrag && (!MainWidgetInterface->GetCutTimeline()->SelectedClips.Contains(ClipData->ClipGuid) || MainWidgetInterface->GetCutTimeline()->SelectedClips.Num() == 1))
|
||||
{
|
||||
const TSharedPtr<FClip2ClipDragDropOperation> Clip2ClipDragDropOperation = MakeShared<FClip2ClipDragDropOperation>();
|
||||
Clip2ClipDragDropOperation->TrackBody = StaticCastSharedPtr<STrackBody>(Body);
|
||||
@ -77,7 +84,7 @@ FReply STimelineClip::OnBorderMouseButtonDown(const FGeometry& Geometry, const F
|
||||
}
|
||||
if (LocalPos.X >= Geometry.GetLocalSize().X - 10)
|
||||
{
|
||||
if (ClipData->bCanDrag && !MainWidgetInterface->GetCutTimeline()->SelectedClips.Contains(ClipData->ClipGuid))
|
||||
if (ClipData->bCanDrag && (!MainWidgetInterface->GetCutTimeline()->SelectedClips.Contains(ClipData->ClipGuid) || MainWidgetInterface->GetCutTimeline()->SelectedClips.Num() == 1))
|
||||
{
|
||||
const TSharedPtr<FClip2ClipDragDropOperation> Clip2ClipDragDropOperation = MakeShared<FClip2ClipDragDropOperation>();
|
||||
Clip2ClipDragDropOperation->TrackBody = StaticCastSharedPtr<STrackBody>(Body);
|
||||
@ -679,6 +686,10 @@ void STimelineClip::UpdateMove(int32 X, int32 DragOffset)
|
||||
FReply STimelineClip::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
||||
{
|
||||
LocalPos = MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition());
|
||||
|
||||
TSharedPtr<STrackBody> NewBody = StaticCastSharedPtr<STrackBody>(Body);
|
||||
|
||||
|
||||
bNeedPaintDrag = false;
|
||||
if (LocalPos.X <= 10)
|
||||
{
|
||||
@ -693,9 +704,14 @@ FReply STimelineClip::OnMouseMove(const FGeometry& MyGeometry, const FPointerEve
|
||||
|
||||
if (MainWidgetInterface->GetSelectedMode() == ESelectMode::CutMode)
|
||||
{
|
||||
float Pos = NewBody->GetCachedGeometry().AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()).X / FGlobalData::DefaultTimeTickSpace;
|
||||
MainWidgetInterface->GetCutTimeline()->CurrentTimeData->SetText(FText::FromString(FGlobalData::GetTimeData(Pos) + " / "));
|
||||
bNeedPaintDrag = true;
|
||||
PaintDragType = 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
@ -863,6 +879,9 @@ FReply STimelineClip::OnDragOver(const FGeometry& MyGeometry, const FDragDropEve
|
||||
|
||||
void STimelineClip::DoSound(ESoundSolveType SolveType, int32 InFrame)
|
||||
{
|
||||
TSharedPtr<STrackBody> NewBody = StaticCastSharedPtr<STrackBody>(Body);
|
||||
if (NewBody->TrackHead->TrackData.IsMute)
|
||||
return;
|
||||
if (SoundThread == nullptr)
|
||||
{
|
||||
if (ClipData->ResourcePropertyDataPtr == nullptr)
|
||||
@ -982,5 +1001,256 @@ void STimelineClip::Tick(const FGeometry& AllottedGeometry, const double InCurre
|
||||
}
|
||||
}
|
||||
|
||||
TSharedPtr<SWidget> STimelineClip::GetPropertiesWidget()
|
||||
{
|
||||
Selectable.Empty();
|
||||
Selectable.Add(MakeShared<FString>(TEXT("无")));
|
||||
Selectable.Add(MakeShared<FString>(TEXT("呼吸")));
|
||||
Selectable.Add(MakeShared<FString>(TEXT("闪烁")));
|
||||
Selectable.Add(MakeShared<FString>(TEXT("渐变")));
|
||||
|
||||
|
||||
FTextBlockStyle NormalText = FAppStyle::GetWidgetStyle<FTextBlockStyle>("NormalText");
|
||||
NormalText.SetFontSize(13);
|
||||
PropertiesWidget =
|
||||
SNew(SVerticalBox)
|
||||
+ SVerticalBox::Slot()
|
||||
.Padding(0, 13, 0, 0)
|
||||
[
|
||||
SNew(SBox).HeightOverride(32).WidthOverride(214)
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+ SHorizontalBox::Slot()
|
||||
.SizeParam(FAuto())
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(SBox)
|
||||
.WidthOverride(62)
|
||||
.HeightOverride(32)
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(FText::FromString(TEXT("颜色")))
|
||||
.Font(NormalText.Font)
|
||||
.Justification(ETextJustify::Center)
|
||||
]
|
||||
]
|
||||
+ SHorizontalBox::Slot()
|
||||
.SizeParam(FAuto())
|
||||
[
|
||||
SNew(SBox)
|
||||
.WidthOverride(136)
|
||||
.HeightOverride(32)
|
||||
[
|
||||
SNew(SImage)
|
||||
.Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("Color.png"), {}))
|
||||
.ColorAndOpacity_Lambda([this]()
|
||||
{
|
||||
if (CustomData.Colors.Num() == 0)
|
||||
{
|
||||
return FLinearColor(1, 1, 1, 0.5);
|
||||
}
|
||||
return CustomData.Colors[0];
|
||||
})
|
||||
.OnMouseButtonDown_Lambda([this](const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
||||
{
|
||||
MainWidgetInterface->OpenColorPanel(&CustomData.Colors[0]);
|
||||
return FReply::Handled();
|
||||
})
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
+ SVerticalBox::Slot()
|
||||
.Padding(0, 13, 0, 0)
|
||||
[
|
||||
SNew(SBox).HeightOverride(32).WidthOverride(214)
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+ SHorizontalBox::Slot()
|
||||
.SizeParam(FAuto())
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(SBox)
|
||||
.WidthOverride(62)
|
||||
.HeightOverride(32)
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(FText::FromString(TEXT("动效")))
|
||||
.Font(NormalText.Font)
|
||||
.Justification(ETextJustify::Center)
|
||||
]
|
||||
]
|
||||
+ SHorizontalBox::Slot()
|
||||
.SizeParam(FAuto())
|
||||
[
|
||||
SNew(SBox)
|
||||
.WidthOverride(136)
|
||||
.HeightOverride(32)
|
||||
[
|
||||
SNew(SComboBox<TSharedPtr<FString>>)
|
||||
.OptionsSource(&Selectable)
|
||||
.OnGenerateWidget_Lambda([this](TSharedPtr<FString> InItem)
|
||||
{
|
||||
return SNew(STextBlock).Text(FText::FromString(*InItem));
|
||||
})
|
||||
.OnSelectionChanged_Lambda([this](TSharedPtr<FString> InItem, ESelectInfo::Type SelectInfo)
|
||||
{
|
||||
switch (Selectable.Find(InItem))
|
||||
{
|
||||
case 0:
|
||||
CustomData.PresetCustomType = FPresetsCustomData::EPresetCustomType::None;
|
||||
break;
|
||||
case 1:
|
||||
CustomData.PresetCustomType = FPresetsCustomData::EPresetCustomType::Breathe;
|
||||
break;
|
||||
case 2:
|
||||
CustomData.PresetCustomType = FPresetsCustomData::EPresetCustomType::Flash;
|
||||
break;
|
||||
case 3:
|
||||
CustomData.PresetCustomType = FPresetsCustomData::EPresetCustomType::Gradient;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
})
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text_Lambda([this]()
|
||||
{
|
||||
return FText::FromString( CustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::None ? TEXT("无") : CustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::Breathe ? TEXT("呼吸") : TEXT("闪烁"));
|
||||
})
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
+ SVerticalBox::Slot()
|
||||
.Padding(0, 13, 0, 0)
|
||||
[
|
||||
SNew(SBox).HeightOverride(32).WidthOverride(214)
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+ SHorizontalBox::Slot()
|
||||
.SizeParam(FAuto())
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(SBox)
|
||||
.WidthOverride(62)
|
||||
.HeightOverride(32)
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(FText::FromString(TEXT("次数")))
|
||||
.Font(NormalText.Font)
|
||||
.Justification(ETextJustify::Center)
|
||||
]
|
||||
]
|
||||
+ SHorizontalBox::Slot()
|
||||
.SizeParam(FAuto())
|
||||
[
|
||||
SNew(SBox)
|
||||
.WidthOverride(136)
|
||||
.HeightOverride(32)
|
||||
[
|
||||
SNew(SSpinBox<int32>)
|
||||
.Value(1)
|
||||
.MinValue(1)
|
||||
.OnValueChanged_Lambda([this](const int32& Value)
|
||||
{
|
||||
CustomData.Times = Value;
|
||||
})
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
+ SVerticalBox::Slot()
|
||||
.Padding(0, 13, 0, 0)
|
||||
[
|
||||
SNew(SBox).HeightOverride(32).WidthOverride(214)
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+ SHorizontalBox::Slot()
|
||||
.SizeParam(FAuto())
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(SBox)
|
||||
.WidthOverride(62)
|
||||
.HeightOverride(32)
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(FText::FromString(TEXT("时间")))
|
||||
.Font(NormalText.Font)
|
||||
.Justification(ETextJustify::Center)
|
||||
]
|
||||
]
|
||||
+ SHorizontalBox::Slot()
|
||||
.SizeParam(FAuto())
|
||||
[
|
||||
SNew(SBox)
|
||||
.WidthOverride(136)
|
||||
.HeightOverride(32)
|
||||
[
|
||||
SNew(SSpinBox<float>)
|
||||
.Value(0.3)
|
||||
.MinValue(0.3)
|
||||
.OnValueChanged_Lambda([this](const float& Value)
|
||||
{
|
||||
CustomData.Time = Value;
|
||||
})
|
||||
// .TypeInterface(MakeShared<TNumericUnitTypeInterface<int32>>(EUnit::Seconds))
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
+ SVerticalBox::Slot()
|
||||
.SizeParam(FStretch(1.0))
|
||||
[
|
||||
SNew(SSpacer)
|
||||
]
|
||||
+ SVerticalBox::Slot()
|
||||
.HAlign(HAlign_Center)
|
||||
.VAlign(VAlign_Bottom)
|
||||
.Padding(0, 0, 0, 24)
|
||||
[
|
||||
SNew(SBox).HeightOverride(40).WidthOverride(144)
|
||||
[
|
||||
SNew(SOverlay)
|
||||
+ SOverlay::Slot()
|
||||
.HAlign(HAlign_Fill)
|
||||
.VAlign(VAlign_Fill)
|
||||
[
|
||||
SNew(SImage)
|
||||
.Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("SaveCustomPreset.png"), {144, 40}))
|
||||
.OnMouseButtonDown_Lambda([this](const FGeometry&, const FPointerEvent&)
|
||||
{
|
||||
TSharedPtr<SNewProjectTips> NewProjectTips = SNew(SNewProjectTips).Title(TEXT("保存自定义效果名称"));
|
||||
NewProjectTips->OnEnsure.BindLambda([this, NewProjectTips](const FString& String)
|
||||
{
|
||||
MainWidgetInterface->AddNewCustomPreset(String, CustomData);
|
||||
GEngine->GameViewport->RemoveViewportWidgetContent(NewProjectTips.ToSharedRef());
|
||||
});
|
||||
GEngine->GameViewport->AddViewportWidgetContent(NewProjectTips.ToSharedRef()
|
||||
, 1);
|
||||
return FReply::Handled();
|
||||
})
|
||||
]
|
||||
+ SOverlay::Slot()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Visibility(EVisibility::HitTestInvisible)
|
||||
.Text(FText::FromString((TEXT("保存自定义效果"))))
|
||||
.Font(NormalText.Font)
|
||||
.Justification(ETextJustify::Center)
|
||||
]
|
||||
]
|
||||
];
|
||||
// TODO: 配置文件保存自定义效果
|
||||
// TODO: 自定义效果拖拽到轨道
|
||||
|
||||
return PropertiesWidget;
|
||||
}
|
||||
|
||||
|
||||
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
|
||||
#include "Cut5/Interface/SoundInterface.h"
|
||||
#include "Widgets/Input/SComboBox.h"
|
||||
#include "Widgets/Layout/SBox.h"
|
||||
extern "C"
|
||||
{
|
||||
@ -21,7 +22,7 @@ extern "C"
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class CUT5_API STimelineClip : public SCompoundWidget
|
||||
class CUT5_API STimelineClip : public SCompoundWidget, public IPropertiesInterface
|
||||
{
|
||||
public:
|
||||
SLATE_BEGIN_ARGS(STimelineClip)
|
||||
@ -72,5 +73,11 @@ public:
|
||||
|
||||
|
||||
FTimelinePropertyData ThumbnailCodecContext;
|
||||
|
||||
|
||||
virtual TSharedPtr<SWidget> GetPropertiesWidget() override;
|
||||
TSharedPtr<SComboBox<TSharedPtr<FString>>> GroupComboBox;
|
||||
TArray<TSharedPtr<FString>> Selectable;
|
||||
FPresetsCustomData CustomData;
|
||||
};
|
||||
|
||||
|
@ -31,7 +31,7 @@ void STrackHead::Construct(const FArguments& InArgs)
|
||||
}));
|
||||
|
||||
}));
|
||||
TSharedPtr<SImage> Image = SNew(SImage);
|
||||
Image = SNew(SImage);
|
||||
ChildSlot
|
||||
[
|
||||
SNew(SBox)
|
||||
@ -103,6 +103,11 @@ void STrackHead::Construct(const FArguments& InArgs)
|
||||
|
||||
FSlateDynamicImageBrush* Brush = new FSlateDynamicImageBrush(*(ImagePath), FVector2D(48, 48));
|
||||
Image->SetImage(Brush);
|
||||
|
||||
if (TrackData.TrackType == ETrackType::VideoTrack || TrackData.TrackType == ETrackType::AudioTrackR || TrackData.TrackType == ETrackType::AudioTrack)
|
||||
{
|
||||
Image->SetColorAndOpacity(TrackData.IsMute ? FLinearColor(1, 0.5, 0.5, 1) : FLinearColor(1, 1, 1, 1));
|
||||
}
|
||||
}
|
||||
|
||||
FReply STrackHead::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
||||
@ -113,7 +118,15 @@ FReply STrackHead::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointer
|
||||
MenuBuilder.AddMenuEntry(FTimelineTrackCommands::Get().Remove);
|
||||
FSlateApplication::Get().PushMenu(AsShared(), FWidgetPath(), MenuBuilder.MakeWidget(), FSlateApplication::Get().GetCursorPos(), FPopupTransitionEffect(FPopupTransitionEffect::ContextMenu));
|
||||
}
|
||||
//
|
||||
if (MouseEvent.IsMouseButtonDown(EKeys::LeftMouseButton))
|
||||
{
|
||||
if (TrackData.TrackType == ETrackType::VideoTrack || TrackData.TrackType == ETrackType::AudioTrackR || TrackData.TrackType == ETrackType::AudioTrack)
|
||||
{
|
||||
TrackData.IsMute = !TrackData.IsMute;
|
||||
Image->SetColorAndOpacity(TrackData.IsMute ? FLinearColor(1, 0.5, 0.5, 1) : FLinearColor(1, 1, 1, 1));
|
||||
}
|
||||
|
||||
}
|
||||
return FReply::Unhandled();
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,10 @@ public:
|
||||
|
||||
FTrackData TrackData;
|
||||
TSharedPtr<SCutTimeline> CutTimeline;
|
||||
TSharedPtr<SImage> Image;
|
||||
ICutMainWidgetInterface* MainWidgetInterface;
|
||||
FString GroupName;
|
||||
virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
|
||||
|
||||
bool bIsMute = false;
|
||||
TSharedPtr<FUICommandList> CommandList;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user