进行保存

This commit is contained in:
Sch 2023-08-08 21:52:00 +08:00
parent a7295dc87b
commit b9ee84436e
34 changed files with 607 additions and 267 deletions

BIN
Resources/Collapse.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

BIN
Resources/Expaned.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 B

View File

@ -52,4 +52,9 @@ public:
virtual void UpdateProperties(IPropertiesInterface* Interface) {};
virtual void ClearProperties() {};
FGuid CurrentSelectedPropertiesInterfaceGuid;
virtual void DeleteAllAssetsInTimeline() {};
virtual class SCutTimeline* GetCutTimeline() { return nullptr; };
};

View File

@ -33,6 +33,7 @@ public:
};
static FString MainSaveFullPath()
{
GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Blue, FGlobalData::BasePath);
return FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName, FGlobalData::CurrentProjectName + TEXT(".bin"));
};
};

View File

@ -27,6 +27,7 @@ public:
virtual void Seek(int32 Frame) {};
virtual void RemoveClip(const FGuid& Guid) {};
virtual void BreakClip(const FGuid& Guid) {};
virtual void DeleteUseLessClips() {};
FGuid SelectedClipGUID;
int32 SelectedClipFrame;

View File

@ -10,5 +10,6 @@ void FCurtainCommands::RegisterCommands()
UI_COMMAND(MoveDown, "下移一层", "Executes My FCurtainCommands", EUserInterfaceActionType::Button, FInputChord());
UI_COMMAND(InsertUp, "在上方插入单元", "Executes My FCurtainCommands", EUserInterfaceActionType::Button, FInputChord());
UI_COMMAND(InsertDown, "在下方插入单元", "Executes My FCurtainCommands", EUserInterfaceActionType::Button, FInputChord());
UI_COMMAND(Delete, "删除", "Executes My FCurtainCommands", EUserInterfaceActionType::Button, FInputChord());
}
#undef LOCTEXT_NAMESPACE

View File

@ -15,4 +15,5 @@ public:
TSharedPtr<FUICommandInfo> MoveDown;
TSharedPtr<FUICommandInfo> InsertUp;
TSharedPtr<FUICommandInfo> InsertDown;
TSharedPtr<FUICommandInfo> Delete;
};

View File

@ -32,6 +32,11 @@ void SCurtain::Construct(const FArguments& InArgs)
.Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("BackGround.png"), {}))
.OnMouseButtonDown_Lambda([this](const FGeometry& Geometry, const FPointerEvent& Event)
{
if (Event.GetEffectingButton() == EKeys::RightMouseButton)
{
CurtainPanel->ShowCurtainCommand(Curtain->CurtainUUID);
return FReply::Handled();
}
CurtainPanel->DeSelectedAll();
Curtain->bIsActive = true;
CurtainPanel->CallRender();
@ -48,7 +53,7 @@ void SCurtain::Construct(const FArguments& InArgs)
.HAlign(HAlign_Left)
.VAlign(VAlign_Center)
[
SNew(SInlineEditableTextBlock)
SAssignNew(InlineEditableTextBlock, SInlineEditableTextBlock)
.Text(FText::FromString(Curtain->CurtainName))
.OnTextCommitted_Lambda([this](const FText& Text, ETextCommit::Type CommitType)
{
@ -87,7 +92,7 @@ FReply SCurtain::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEv
{
if (MouseEvent.GetEffectingButton() == EKeys::RightMouseButton)
{
CurtainPanel->ShowCurtainCommand(0);
CurtainPanel->ShowCurtainCommand(Curtain->CurtainUUID);
return FReply::Handled();
}
return SCompoundWidget::OnMouseButtonDown(MyGeometry, MouseEvent);

View File

@ -30,4 +30,5 @@ public:
FCurtain* Curtain;
FCurtainGroup* CurtainGroup;
int32 CurtainIndex;
TSharedPtr<SInlineEditableTextBlock> InlineEditableTextBlock;
};

View File

@ -62,7 +62,7 @@ void SCurtainGroup::Construct(const FArguments& InArgs)
// .Style(&ExpandableAreaStyle)
.HeaderContent()
[
SNew(SInlineEditableTextBlock)
SAssignNew(InlineEditableTextBlock, SInlineEditableTextBlock)
.Text(FText::FromString(CurtainGroup->GroupName))
.OnVerifyTextChanged_Lambda([](const FText& Text, FText& ErrorMessage)
{
@ -90,16 +90,21 @@ void SCurtainGroup::Construct(const FArguments& InArgs)
void SCurtainGroup::CallRender()
{
ContentVerticalBox->ClearChildren();
CurtainWidgets.Empty();
for (FCurtain& Curtain : CurtainGroup->Curtains)
{
ContentVerticalBox->AddSlot()
[
TSharedPtr<SCurtain> CurtainWidget =
SNew(SCurtain)
.Curtain(&Curtain)
.CurtainGroup(CurtainGroup)
.CurtainPanel(CurtainPanel)
.CurtainIndex(&Curtain - &CurtainGroup->Curtains[0])
.CurtainIndex(&Curtain - &CurtainGroup->Curtains[0]);
ContentVerticalBox->AddSlot()
[
CurtainWidget.ToSharedRef()
];
CurtainWidgets.Add(CurtainWidget);
}
}
@ -117,4 +122,14 @@ FReply SCurtainGroup::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent&
return FReply::Handled();
}
FReply SCurtainGroup::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
if (MouseEvent.IsMouseButtonDown(EKeys::RightMouseButton))
{
CurtainPanel->ShowCurtainCommand(CurtainGroup->GroupUID);
return FReply::Handled();
}
return FReply::Handled();
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

View File

@ -3,6 +3,7 @@
#pragma once
#include "CoreMinimal.h"
#include "SCurtain.h"
#include "Cut5/Widgets/DefineGlobal.h"
#include "Widgets/SCompoundWidget.h"
@ -31,4 +32,10 @@ public:
void CallRender();
virtual FReply OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override;
virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
TSharedPtr<SInlineEditableTextBlock> InlineEditableTextBlock;
TArray<TSharedPtr<SCurtain>> CurtainWidgets;
};

View File

@ -12,6 +12,7 @@
#include "Cut5/Widgets/Commands/CurtainCommands.h"
#include "Widgets/Layout/SScrollBox.h"
#include "Widgets/Layout/SSeparator.h"
#include "Widgets/Text/SInlineEditableTextBlock.h"
#include "Widgets/Views/STreeView.h"
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
@ -31,9 +32,9 @@ void SCurtainPanel::Construct(const FArguments& InArgs)
{
}));
CommandList->MapAction(FCurtainCommands::Get().Rename, FExecuteAction::CreateLambda([]()
CommandList->MapAction(FCurtainCommands::Get().Rename, FExecuteAction::CreateLambda([this]()
{
RenameCurtain();
}));
CommandList->MapAction(FCurtainCommands::Get().MoveUp, FExecuteAction::CreateLambda([]()
{
@ -51,7 +52,10 @@ void SCurtainPanel::Construct(const FArguments& InArgs)
{
}));
CommandList->MapAction(FCurtainCommands::Get().Delete, FExecuteAction::CreateLambda([this]()
{
RemoveCurtain();
}));
FTextBlockStyle NormalText = FAppStyle::GetWidgetStyle<FTextBlockStyle>("NormalText");
NormalText.SetFontSize(15);
@ -209,14 +213,18 @@ void SCurtainPanel::UnSelectAllCurtain()
void SCurtainPanel::CallRender()
{
ScrollBox->ClearChildren();
GroupWidgets.Empty();
for (FCurtainGroup& Group : Groups)
{
ScrollBox->AddSlot()
[
TSharedPtr<SCurtainGroup> NewGroup =
SNew(SCurtainGroup)
.CurtainGroup(&Group)
.CurtainPanel(this)
.CurtainPanel(this);
ScrollBox->AddSlot()
[
NewGroup.ToSharedRef()
];
GroupWidgets.Add(NewGroup);
}
}
@ -257,8 +265,11 @@ void SCurtainPanel::Move(int32 SrcCurtainIndex, int32 DstCurtainIndex, int32 Src
CallRender();
}
void SCurtainPanel::ShowCurtainCommand(int32 Index)
void SCurtainPanel::ShowCurtainCommand(const FGuid& Guid)
{
SelectedGuid = Guid;
FMenuBuilder MenuBuilder(true, CommandList);
MenuBuilder.AddMenuEntry(FCurtainCommands::Get().Copy);
MenuBuilder.AddMenuEntry(FCurtainCommands::Get().Paste);
@ -267,10 +278,83 @@ void SCurtainPanel::ShowCurtainCommand(int32 Index)
MenuBuilder.AddMenuEntry(FCurtainCommands::Get().InsertDown);
MenuBuilder.AddMenuEntry(FCurtainCommands::Get().MoveUp);
MenuBuilder.AddMenuEntry(FCurtainCommands::Get().MoveDown);
MenuBuilder.AddMenuEntry(FCurtainCommands::Get().Delete);
// MenuBuilder.AddWidget(
// SNew(SBox)
// .WidthOverride(160)
// .HeightOverride(40)
// [
// SNew(SButton)
// [
// SNew(STextBlock)
// .Text(FText::FromString(TEXT("删除")))
// ]
// ]
//
// , FText::FromString(TEXT("删除")), true);
TSharedPtr<SWidget> MenuContent;
MenuContent = MenuBuilder.MakeWidget();
FSlateApplication::Get().PushMenu(AsShared(), FWidgetPath(), MenuContent.ToSharedRef(), FSlateApplication::Get().GetCursorPos(), FPopupTransitionEffect::ContextMenu);
}
void SCurtainPanel::RemoveCurtain()
{
int32 j = 0;
for (FCurtainGroup& Group : Groups)
{
if (Group.GroupUID == SelectedGuid)
{
Groups.RemoveAt(j);
SelectedGuid.Invalidate();
CallRender();
return;
}
int32 i = 0;
for (FCurtain& Curtain : Group.Curtains)
{
if (Curtain.CurtainUUID == SelectedGuid)
{
Group.Curtains.RemoveAt(i);
SelectedGuid.Invalidate();
CallRender();
return;
}
i++;
}
j++;
}
}
void SCurtainPanel::RenameCurtain()
{
int32 j = 0;
for (TSharedPtr<SCurtainGroup> Group : GroupWidgets)
{
if (Group->CurtainGroup->GroupUID == SelectedGuid)
{
FSlateApplication::Get().SetKeyboardFocus(Group->InlineEditableTextBlock);
Group->InlineEditableTextBlock->EnterEditingMode();
Group->InlineEditableTextBlock->EnterEditingMode();
return;
}
int32 i = 0;
for (TSharedPtr<SCurtain> Curtain : Group->CurtainWidgets)
{
if (Curtain->Curtain->CurtainUUID == SelectedGuid)
{
FSlateApplication::Get().SetKeyboardFocus(Curtain->InlineEditableTextBlock);
Curtain->InlineEditableTextBlock->EnterEditingMode();
Curtain->InlineEditableTextBlock->EnterEditingMode();
return;
}
i++;
}
j++;
}
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

View File

@ -37,7 +37,9 @@ public:
void CallRender();
void DeSelectedAll();
void Move(int32 SrcCurtainIndex = 0, int32 DstCurtainIndex = 0, int32 SrcGroupIndex = 0, int32 DstGroupIndex = 0);
void ShowCurtainCommand(int32 Index);
void ShowCurtainCommand(const FGuid& Guid);
void RemoveCurtain();
void RenameCurtain();
ICutMainWidgetInterface* MainWidgetInterface = nullptr;
int32 CurrentSelectedTree = 0;
TArray<TSharedPtr<SCurtainTree>> Trees;
@ -45,4 +47,7 @@ public:
TSharedPtr<FUICommandList> CommandList;
TSharedPtr<STextBlock> Title;
TArray<FCurtainGroup> Groups;
FGuid SelectedGuid = FGuid();
TArray<TSharedPtr<SCurtainGroup>> GroupWidgets;
};

View File

@ -1,5 +1,6 @@
#pragma once
#include "Cut5/WidgetInterface.h"
#include "Widgets/Input/SEditableTextBox.h"
extern "C"{
@ -71,6 +72,9 @@ enum class ETrackType
ProjectorTrack,
LightArrayTrack,
LightBarTrack,
CustomColorTrack,
None = 255,
};
enum class EPresetType
@ -113,8 +117,14 @@ struct CUT5_API FTrackData
};
struct CUT5_API FCursorData
{
FCursorData(int32 Offset, FLinearColor InColor)
{
CursorFrameOffset = Offset;
Color = InColor;
};
int32 CursorFrameOffset = 0;
FLinearColor Color;
friend FArchive& operator<<(FArchive& Ar, FCursorData& CursorData)
{
Ar << CursorData.CursorFrameOffset;
@ -240,6 +250,7 @@ struct CUT5_API FTimelinePropertyData
Type = InType;
IconPath = InIconPath;
}
bool bIsValid = true;
FString Name = "";
ETrackType Type = ETrackType::VideoTrack;
@ -294,6 +305,9 @@ public:
TickDrag,
CurtainDrag,
EffectCardDrag,
Device,
PresetDrag,
CursorDrag,
};
FCutDragDropBase() {};
FCutDragDropBase(EType InType)
@ -303,8 +317,10 @@ public:
TSharedPtr<SWidget> DraggingWidget;
TSharedPtr<IWidgetInterface> OverrideWidget;
TSharedPtr<IWidgetInterface> MoveAboutWidget;
class ICutMainWidgetInterface* MainInterface;
float DragOffset = 0.0f;
EType DragDropType = EType::TrackClip;
ETrackType ManualClipType = ETrackType::None;
};
@ -314,6 +330,13 @@ public:
// It's a Ptr to Resource;
FTimelinePropertyData* TimelinePropertyData = nullptr;
cv::VideoCapture* VideoCapture;
};
class CUT5_API FPresetDragOperation final : public FCutDragDropBase
{
public:
// It's a Ptr to Resource;
FPresetsData PresetData = FPresetsData();
};
@ -345,6 +368,20 @@ public:
FGuid CardGuid;
};
class CUT5_API FDeviceDragDrop final : public FCutDragDropBase
{
public:
ETrackType TrackType;
FString DeviceName;
};
class CUT5_API FCursorDragDrop final : public FCutDragDropBase
{
public:
FCursorData* CursorData;
FClipData* ClipData;
};
struct FTimelineInfo;
struct CUT5_API FTimelineInfo
{
@ -419,7 +456,7 @@ class FCurtain
{
public:
FString CurtainName = TEXT("新建幕");
FGuid CurtainUUID;
FGuid CurtainUUID = FGuid::NewGuid();
bool bIsActive = false;
friend FArchive& operator<< (FArchive& Ar, FCurtain& Curtain)
@ -433,7 +470,7 @@ class FCurtainGroup
{
public:
FString GroupName = TEXT("新建组");
FGuid GroupUID;
FGuid GroupUID = FGuid::NewGuid();
TArray<FCurtain> Curtains;
bool bIsActive = false;

View File

@ -19,6 +19,22 @@ DragDropOperator* DragDropOperator::GetDragDropOperator()
void DragDropOperator::OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent)
{
if (TSharedPtr<FCursorDragDrop> DragDrop = DragDropEvent.GetOperationAs<FCursorDragDrop>())
{
if (DragDrop->DragDropType == FCutDragDropBase::EType::CursorDrag)
{
TSharedPtr<STrackBody> Body = StaticCastSharedPtr<STrackBody>(DragDrop->OverrideWidget);
const FVector2D LocalPos = Body->GetCachedGeometry().AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition());
if (LocalPos.X <= DragDrop->ClipData->ClipStartFrame * FGlobalData::DefaultTimeTickSpace || LocalPos.X >= DragDrop->ClipData->ClipEndFrame * FGlobalData::DefaultTimeTickSpace)
{
return;
}
float Offset = LocalPos.X;
DragDrop->CursorData->CursorFrameOffset = Offset / FGlobalData::DefaultTimeTickSpace - DragDrop->ClipData->ClipStartFrame;
}
}
const auto& DragDropOperation = static_cast<FClip2ClipDragDropOperation&>(DragDropEvent.GetOperation().ToSharedRef().Get());
TSharedPtr<STrackBody> Body = StaticCastSharedPtr<STrackBody>(DragDropOperation.OverrideWidget);
@ -49,6 +65,37 @@ void DragDropOperator::OnDragOver(const FGeometry& MyGeometry, const FDragDropEv
void DragDropOperator::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent, TSharedPtr<SWidget> DropWidget)
{
const auto& DragDropOperation = static_cast<FTrackClipDragOperation&>(DragDropEvent.GetOperation().ToSharedRef().Get());
if (DragDropOperation.DragDropType == FCutDragDropBase::EType::PresetDrag)
{
TSharedPtr<FPresetDragOperation> PresetDragOperation = DragDropEvent.GetOperationAs<FPresetDragOperation>();
TSharedPtr<STrackBody> TrackBody = StaticCastSharedPtr<STrackBody>(DropWidget);
TSharedPtr<STrackHead> TrackHead = TrackBody->TrackHead;
FClipData NewClipData;
NewClipData.PresetType = PresetDragOperation->PresetData.PresetType;
NewClipData.ClipGuid = FGuid::NewGuid();
NewClipData.ClipType = PresetDragOperation->ManualClipType;
NewClipData.ClipStartFrame = MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X / FGlobalData::DefaultTimeTickSpace;
NewClipData.ClipEndFrame = (MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X + 100) / FGlobalData::DefaultTimeTickSpace;
NewClipData.ClipColors.Add(FLinearColor(1, 1, 1, 1));
NewClipData.Cursors.Add(FCursorData(0, FLinearColor(1, 0, 0, 1)));
NewClipData.Cursors.Add(FCursorData(5, FLinearColor(0, 1, 1, 1)));
TrackHead->TrackData.ClipData.Add(NewClipData);
TrackBody->CallRender();
return;
}
if (DragDropOperation.DragDropType == FCutDragDropBase::EType::Device)
{
TSharedPtr<STrackBody> TrackBody = StaticCastSharedPtr<STrackBody>(DropWidget);
TSharedPtr<STrackHead> TrackHead = TrackBody->TrackHead;
TSharedPtr<FDeviceDragDrop> CutDragDropBase = DragDropEvent.GetOperationAs<FDeviceDragDrop>();
FTrackData NewTrackData;
NewTrackData.TrackType = CutDragDropBase->TrackType;
NewTrackData.TrackName = CutDragDropBase->DeviceName;
CutDragDropBase->MainInterface->GetCutTimeline()->AddNewTrackToGroup(TrackHead->GroupName, NewTrackData);
CutDragDropBase->MainInterface->OnAddNewTrack(ETrackType::PlayerTrack);
return;
}
if (DragDropOperation.DragDropType == FCutDragDropBase::EType::TrackClip)
{
TSharedPtr<STrackBody> TrackBody = StaticCastSharedPtr<STrackBody>(DropWidget);
@ -62,7 +109,8 @@ void DragDropOperator::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent&
{
if ((ClipDragOperation.TimelinePropertyData->Type == ETrackType::VideoTrack && TrackHead->TrackData.TrackType == ETrackType::LightArrayTrack)
|| (ClipDragOperation.TimelinePropertyData->Type == ETrackType::VideoTrack && TrackHead->TrackData.TrackType == ETrackType::PlayerTrack)
|| (ClipDragOperation.TimelinePropertyData->Type == ETrackType::AudioTrack && TrackHead->TrackData.TrackType == ETrackType::AudioTrackR))
|| (ClipDragOperation.TimelinePropertyData->Type == ETrackType::AudioTrack && TrackHead->TrackData.TrackType == ETrackType::AudioTrackR)
|| (ClipDragOperation.TimelinePropertyData->Type == ETrackType::VideoTrack && TrackHead->TrackData.TrackType == ETrackType::AtomSphereLightTrack))
{
}
@ -72,168 +120,109 @@ void DragDropOperator::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent&
}
}
if (ClipDragOperation.PresetData.PresetType != EPresetType::NotAPresets)
FClipData NewClipData;
NewClipData.ClipGuid = FGuid::NewGuid();
NewClipData.ClipType = TrackHead->TrackData.TrackType;
NewClipData.ClipStartFrame = MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X / FGlobalData::DefaultTimeTickSpace;
NewClipData.ClipColors.Add(FLinearColor(1, 1, 1, 1));
NewClipData.ResourcePropertyGuid = ClipDragOperation.TimelinePropertyData->Guid;
NewClipData.ResourcePropertyDataPtr = ClipDragOperation.TimelinePropertyData;
if (ClipDragOperation.TimelinePropertyData->Type == ETrackType::VideoTrack)
{
FClipData NewClipData;
NewClipData.ClipGuid = FGuid::NewGuid();
NewClipData.ClipType = ClipDragOperation.TimelinePropertyData->Type;
NewClipData.ClipStartFrame = MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X / FGlobalData::DefaultTimeTickSpace;
switch (ClipDragOperation.PresetData.PresetType)
// 如果拖拽物是视频,那么对不同轨道进行不同和操作
NewClipData.MoviePath = ClipDragOperation.TimelinePropertyData->MoviePath;
NewClipData.ClipEndFrame = NewClipData.ClipStartFrame + ClipDragOperation.TimelinePropertyData->MovieFrameLength;
NewClipData.VideoCapture = ClipDragOperation.VideoCapture;
if (TrackHead->TrackData.TrackType == ETrackType::LightArrayTrack)
{
case EPresetType::Color:
NewClipData.ClipType = ETrackType::LightArrayTrack;
NewClipData.LightArrayData = FOpencvUtils::GetVideoFrameLightArray(ClipDragOperation.TimelinePropertyData->MoviePath, FGlobalData::LightArrayX, FGlobalData::LightArrayY);
}
if (TrackHead->TrackData.TrackType == ETrackType::PlayerTrack)
{
NewClipData.ClipType = ETrackType::PlayerTrack;
NewClipData.PlayerName = TrackBody->MainWidgetInterface->GetGroupName(TrackHead);
NewClipData.PlayerLightData = FOpencvUtils::GetVideoSingleLightColor(ClipDragOperation.TimelinePropertyData->MoviePath);
}
if (TrackHead->TrackData.TrackType == ETrackType::AtomSphereLightTrack)
{
NewClipData.ClipType = ETrackType::AtomSphereLightTrack;
NewClipData.PlayerName = TrackBody->MainWidgetInterface->GetGroupName(TrackHead);
NewClipData.PlayerLightData = FOpencvUtils::GetVideoSingleLightColor(ClipDragOperation.TimelinePropertyData->MoviePath);
}
if (TrackHead->TrackData.TrackType == ETrackType::VideoTrack)
{
SCutMainWindow* MainWidget = static_cast<SCutMainWindow*>(TrackHead->MainWidgetInterface);
if (!MainWidget->CutTimeline->GetTrackGroupByName(TEXT("视频附着")))
{
MainWidget->CutTimeline->AddNewTrackToGroup(TEXT("视频附着"), FTrackData(TEXT("附着音频"), ETrackType::AudioTrack));
}
break;
case EPresetType::Video:
break;
case EPresetType::Gradient:
break;
default:
break;
}
//Overwrite the clip if it is in the same position
for (int32 i = TrackHead->TrackData.ClipData.Num() - 1; i >= 0; i--)
{
const int32 ClipStartFrame = TrackHead->TrackData.ClipData[i].ClipStartFrame;
const int32 ClipEndFrame = TrackHead->TrackData.ClipData[i].ClipEndFrame;
if (NewClipData.ClipStartFrame >= ClipStartFrame && NewClipData.ClipEndFrame <= ClipEndFrame)
{
// It mean the new clip is in the old clip
FClipData SaveClipData = TrackHead->TrackData.ClipData[i];
TrackHead->TrackData.ClipData.RemoveAt(i);
// Left
FClipData LeftClipData = SaveClipData;
LeftClipData.ClipEndFrame = NewClipData.ClipStartFrame;
TrackHead->TrackData.ClipData.Add(LeftClipData);
FClipData RightClipData = SaveClipData;
RightClipData.ClipStartFrame = NewClipData.ClipEndFrame;
TrackHead->TrackData.ClipData.Add(RightClipData);
continue;
}
if (NewClipData.ClipStartFrame <= ClipEndFrame && NewClipData.ClipEndFrame >= ClipEndFrame)
{
// It mean the new clip start point is in the old clip
TrackHead->TrackData.ClipData[i].CropClip(FClipData::ECropMethod::FromBack, (ClipEndFrame - NewClipData.ClipStartFrame));
continue;
}
if (NewClipData.ClipEndFrame > ClipStartFrame && NewClipData.ClipStartFrame < ClipStartFrame)
{
// It mean the new clip end point is in the old clip
TrackHead->TrackData.ClipData[i].CropClip(FClipData::ECropMethod::FromFront, (NewClipData.ClipEndFrame - ClipStartFrame));
continue;
}
if (NewClipData.ClipStartFrame <= ClipStartFrame && NewClipData.ClipEndFrame >= ClipEndFrame)
{
// It mean the new clip is out of the old clip
TrackHead->TrackData.ClipData.RemoveAt(i);
continue;
}
}
TrackHead->TrackData.ClipData.Add(NewClipData);
}
else
else if (ClipDragOperation.TimelinePropertyData->Type == ETrackType::LightArrayTrack)
{
FClipData NewClipData;
NewClipData.ClipGuid = FGuid::NewGuid();
NewClipData.ClipType = ClipDragOperation.TimelinePropertyData->Type;
NewClipData.ClipStartFrame = MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X / FGlobalData::DefaultTimeTickSpace;
NewClipData.ClipColors.Add(FLinearColor(1, 1, 1, 1));
NewClipData.ResourcePropertyGuid = ClipDragOperation.TimelinePropertyData->Guid;
NewClipData.ResourcePropertyDataPtr = ClipDragOperation.TimelinePropertyData;
if (ClipDragOperation.TimelinePropertyData->Type == ETrackType::VideoTrack)
{
// 如果拖拽物是视频,那么对不同轨道进行不同和操作
NewClipData.MoviePath = ClipDragOperation.TimelinePropertyData->MoviePath;
NewClipData.ClipEndFrame = NewClipData.ClipStartFrame + ClipDragOperation.TimelinePropertyData->MovieFrameLength;
NewClipData.VideoCapture = ClipDragOperation.VideoCapture;
if (TrackHead->TrackData.TrackType == ETrackType::LightArrayTrack)
{
NewClipData.ClipType = ETrackType::LightArrayTrack;
NewClipData.LightArrayData = FOpencvUtils::GetVideoFrameLightArray(ClipDragOperation.TimelinePropertyData->MoviePath, FGlobalData::LightArrayX, FGlobalData::LightArrayY);
}
if (TrackHead->TrackData.TrackType == ETrackType::PlayerTrack)
{
NewClipData.ClipType = ETrackType::PlayerTrack;
NewClipData.PlayerName = TrackBody->MainWidgetInterface->GetGroupName(TrackHead);
NewClipData.PlayerLightData = FOpencvUtils::GetVideoSingleLightColor(ClipDragOperation.TimelinePropertyData->MoviePath);
}
if (TrackHead->TrackData.TrackType == ETrackType::VideoTrack)
{
SCutMainWindow* MainWidget = static_cast<SCutMainWindow*>(TrackHead->MainWidgetInterface);
if (!MainWidget->CutTimeline->GetTrackGroupByName(TEXT("视频附着")))
{
MainWidget->CutTimeline->AddNewTrackToGroup(TEXT("视频附着"), FTrackData(TEXT("附着音频"), ETrackType::AudioTrack));
}
}
}
else if (ClipDragOperation.TimelinePropertyData->Type == ETrackType::LightArrayTrack)
{
NewClipData.ClipEndFrame = NewClipData.ClipStartFrame + 200;
}
// 如果拖拽物是音频
else if (ClipDragOperation.TimelinePropertyData->Type == ETrackType::AudioTrack)
{
NewClipData.MoviePath = ClipDragOperation.TimelinePropertyData->MoviePath;
NewClipData.ClipEndFrame = NewClipData.ClipStartFrame + ClipDragOperation.TimelinePropertyData->MovieFrameLength;
NewClipData.VideoEndFrame = ClipDragOperation.TimelinePropertyData->MovieFrameLength;
NewClipData.ResourcePropertyDataPtr = ClipDragOperation.TimelinePropertyData;
}
//Overwrite the clip if it is in the same position
for (int32 i = TrackHead->TrackData.ClipData.Num() - 1; i >= 0; i--)
{
const int32 ClipStartFrame = TrackHead->TrackData.ClipData[i].ClipStartFrame;
const int32 ClipEndFrame = TrackHead->TrackData.ClipData[i].ClipEndFrame;
if (NewClipData.ClipStartFrame >= ClipStartFrame && NewClipData.ClipEndFrame <= ClipEndFrame)
{
// It mean the new clip is in the old clip
FClipData SaveClipData = TrackHead->TrackData.ClipData[i];
TrackHead->TrackData.ClipData.RemoveAt(i);
// Left
FClipData LeftClipData = SaveClipData;
LeftClipData.ClipEndFrame = NewClipData.ClipStartFrame;
TrackHead->TrackData.ClipData.Add(LeftClipData);
FClipData RightClipData = SaveClipData;
RightClipData.ClipStartFrame = NewClipData.ClipEndFrame;
TrackHead->TrackData.ClipData.Add(RightClipData);
continue;
}
if (NewClipData.ClipStartFrame <= ClipEndFrame && NewClipData.ClipEndFrame >= ClipEndFrame)
{
// It mean the new clip start point is in the old clip
TrackHead->TrackData.ClipData[i].CropClip(FClipData::ECropMethod::FromBack, (ClipEndFrame - NewClipData.ClipStartFrame));
continue;
}
if (NewClipData.ClipEndFrame > ClipStartFrame && NewClipData.ClipStartFrame < ClipStartFrame)
{
// It mean the new clip end point is in the old clip
TrackHead->TrackData.ClipData[i].CropClip(FClipData::ECropMethod::FromFront, (NewClipData.ClipEndFrame - ClipStartFrame));
continue;
}
if (NewClipData.ClipStartFrame <= ClipStartFrame && NewClipData.ClipEndFrame >= ClipEndFrame)
{
// It mean the new clip is out of the old clip
TrackHead->TrackData.ClipData.RemoveAt(i);
continue;
}
}
TrackHead->TrackData.ClipData.Add(NewClipData);
NewClipData.ClipEndFrame = NewClipData.ClipStartFrame + 200;
}
// 如果拖拽物是音频
else if (ClipDragOperation.TimelinePropertyData->Type == ETrackType::AudioTrack)
{
NewClipData.MoviePath = ClipDragOperation.TimelinePropertyData->MoviePath;
NewClipData.ClipEndFrame = NewClipData.ClipStartFrame + ClipDragOperation.TimelinePropertyData->MovieFrameLength;
NewClipData.VideoEndFrame = ClipDragOperation.TimelinePropertyData->MovieFrameLength;
NewClipData.ResourcePropertyDataPtr = ClipDragOperation.TimelinePropertyData;
}
//Overwrite the clip if it is in the same position
for (int32 i = TrackHead->TrackData.ClipData.Num() - 1; i >= 0; i--)
{
const int32 ClipStartFrame = TrackHead->TrackData.ClipData[i].ClipStartFrame;
const int32 ClipEndFrame = TrackHead->TrackData.ClipData[i].ClipEndFrame;
if (NewClipData.ClipStartFrame >= ClipStartFrame && NewClipData.ClipEndFrame <= ClipEndFrame)
{
// It mean the new clip is in the old clip
FClipData SaveClipData = TrackHead->TrackData.ClipData[i];
TrackHead->TrackData.ClipData.RemoveAt(i);
// Left
FClipData LeftClipData = SaveClipData;
LeftClipData.ClipEndFrame = NewClipData.ClipStartFrame;
TrackHead->TrackData.ClipData.Add(LeftClipData);
FClipData RightClipData = SaveClipData;
RightClipData.ClipStartFrame = NewClipData.ClipEndFrame;
TrackHead->TrackData.ClipData.Add(RightClipData);
continue;
}
if (NewClipData.ClipStartFrame <= ClipEndFrame && NewClipData.ClipEndFrame >= ClipEndFrame)
{
// It mean the new clip start point is in the old clip
TrackHead->TrackData.ClipData[i].CropClip(FClipData::ECropMethod::FromBack, (ClipEndFrame - NewClipData.ClipStartFrame));
continue;
}
if (NewClipData.ClipEndFrame > ClipStartFrame && NewClipData.ClipStartFrame < ClipStartFrame)
{
// It mean the new clip end point is in the old clip
TrackHead->TrackData.ClipData[i].CropClip(FClipData::ECropMethod::FromFront, (NewClipData.ClipEndFrame - ClipStartFrame));
continue;
}
if (NewClipData.ClipStartFrame <= ClipStartFrame && NewClipData.ClipEndFrame >= ClipEndFrame)
{
// It mean the new clip is out of the old clip
TrackHead->TrackData.ClipData.RemoveAt(i);
continue;
}
}
TrackHead->TrackData.ClipData.Add(NewClipData);

View File

@ -5,12 +5,15 @@
#include "SlateOptMacros.h"
#include "Cut5/Utils/Utils.h"
#include "Cut5/Widgets/STimelineClip.h"
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SClipCursor::Construct(const FArguments& InArgs)
{
CursorData = InArgs._CursorData;
ClipData = InArgs._ClipData;
TimelineClip = InArgs._TimelineClip;
ChildSlot
[
SNew(SBox)
@ -19,9 +22,23 @@ void SClipCursor::Construct(const FArguments& InArgs)
[
SNew(SImage)
.Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath(TEXT("Cursor.png")), {}))
.OnMouseButtonDown_Lambda([this](const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
const TSharedPtr<FCursorDragDrop> Operation = MakeShared<FCursorDragDrop>();
Operation->DragDropType = FCutDragDropBase::EType::CursorDrag;
Operation->CursorData = CursorData;
Operation->ClipData = ClipData;
Operation->OverrideWidget = TimelineClip->Body;
return FReply::Handled().DetectDrag(SharedThis(this), EKeys::LeftMouseButton).BeginDragDrop(Operation.ToSharedRef());
})
]
];
}
void SClipCursor::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
{
SetRenderTransform(FSlateRenderTransform(FVector2D(CursorData->CursorFrameOffset * FGlobalData::DefaultTimeTickSpace - 11, 0)));
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

View File

@ -3,6 +3,7 @@
#pragma once
#include "CoreMinimal.h"
#include "Cut5/Widgets/DefineGlobal.h"
#include "Widgets/SCompoundWidget.h"
/**
@ -14,9 +15,16 @@ public:
SLATE_BEGIN_ARGS(SClipCursor)
{
}
SLATE_ARGUMENT(FCursorData*, CursorData);
SLATE_ARGUMENT(FClipData*, ClipData);
SLATE_ARGUMENT(class STimelineClip*, TimelineClip);
SLATE_END_ARGS()
/** Constructs this widget with InArgs */
void Construct(const FArguments& InArgs);
virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;
FCursorData* CursorData;
FClipData* ClipData;
class STimelineClip* TimelineClip;
};

View File

@ -13,7 +13,7 @@ void SEffectPreset::Construct(const FArguments& InArgs)
Name = InArgs._Name;
PresetPath = InArgs._PresetPath;
MainInterface = InArgs._MainInterface;
PresetsData.PresetType = EPresetType::Video;
PresetsData.PresetType = EPresetType::Gradient;
ChildSlot
[
SNew(SBox)
@ -294,9 +294,9 @@ TSharedPtr<SWidget> SEffectPreset::GetPropertiesWidget()
FReply SEffectPreset::OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
TSharedPtr<FTrackClipDragOperation> DragOperation = MakeShared<FTrackClipDragOperation>();
TSharedPtr<FPresetDragOperation> DragOperation = MakeShared<FPresetDragOperation>();
DragOperation->DragDropType = FCutDragDropBase::EType::TrackClip;
DragOperation->DragDropType = FCutDragDropBase::EType::PresetDrag;
DragOperation->PresetData = PresetsData;
return FReply::Handled().BeginDragDrop(DragOperation.ToSharedRef());
}

View File

@ -22,6 +22,7 @@
#include "Cut5/Utils/OpencvUtils.h"
#include "Cut5/Utils/Utils.h"
#include "Kismet/GameplayStatics.h"
#include "MicroWidgets/STips.h"
#include "Presets/SEffectPreset.h"
#include "Widgets/Layout/SWidgetSwitcher.h"
@ -207,29 +208,39 @@ void SCustomInputPanel::Construct(const FArguments& InArgs)
{
if (bIsEditMode)
{
for (int32 i = 0; i < SelectedProperties.Num(); i++)
{
for (int32 j = 0; j < ResourceInst.Num(); j++)
GEngine->GameViewport->AddViewportWidgetContent(SNew(STips)
.Title(TEXT("确定删除预设吗?"))
.SubTitle(TEXT("删除整个组和所有组下特效卡的预设且不可恢复")).OnEnsure_Lambda([this](const FString& String)
{
if (ResourceInst[j]->PropertyData.Guid == SelectedProperties[i].Guid)
for (int32 i = 0; i < SelectedProperties.Num(); i++)
{
ResourceInst[j]->ShowCheckBox(false);
ResourceInst[j]->SetVisibility(EVisibility::Collapsed);
ResourceInst.RemoveAt(j);
break;
}
GridPanel->RemoveSlot(ResourceInst[j].ToSharedRef());
}
for (int32 j = 0; j < PropertyData.Num(); j++)
{
if (PropertyData[j].Guid == SelectedProperties[i].Guid)
{
PropertyData.RemoveAt(j);
break;
}
for (int32 j = 0; j < ResourceInst.Num(); j++)
{
if (ResourceInst[j]->PropertyData.Guid == SelectedProperties[i].Guid)
{
ResourceInst[j]->ShowCheckBox(false);
ResourceInst[j]->SetVisibility(EVisibility::Collapsed);
ResourceInst.RemoveAt(j);
break;
}
GridPanel->RemoveSlot(ResourceInst[j].ToSharedRef());
}
for (int32 j = 0; j < PropertyData.Num(); j++)
{
if (PropertyData[j].Guid == SelectedProperties[i].Guid)
{
PropertyData[j].bIsValid = false;
PropertyData.RemoveAt(j);
break;
}
}
}
}
}
MainWidgetInterface->DeleteAllAssetsInTimeline();
}), 1);
return FReply::Handled();
}
IDesktopPlatform* DesktopPlatformModule = FDesktopPlatformModule::Get();

View File

@ -23,6 +23,7 @@
#include "DragDropOperator/DragDropOperator.h"
#include "FX/SEffectCardsPanel.h"
#include "HAL/FileManagerGeneric.h"
#include "Kismet/KismetSystemLibrary.h"
#include "MicroWidgets/SNewProjectTips.h"
#include "StatePanel/SStatePanel.h"
#include "Widgets/Layout/SConstraintCanvas.h"
@ -62,7 +63,7 @@ void SCutMainWindow::Construct(const FArguments& InArgs)
CommandList->MapAction(FMainMenuCommands::Get().Exit, FExecuteAction::CreateLambda([this]()
{
exit(0);
FPlatformMisc::RequestExit(true);
}));
@ -201,6 +202,7 @@ void SCutMainWindow::Construct(const FArguments& InArgs)
// Property Panel
SNew(STimelinePropertyPanel)
.MainWindow(SharedThis(this))
.MainInterface(this)
]
+ SWidgetSwitcher::Slot()
[
@ -274,19 +276,35 @@ void SCutMainWindow::Render()
StatePanel->PlayerList2->ClearChildren();
PlayerLightsSlateInstances.Empty();
bool bSingle = false;
for (FSingleTrackGroupInstance& TrackGroupInstance : CutTimeline->TrackGroupInstances)
for (FTrackGroup& TrackGroup : CutTimeline->TrackGroups)
{
if (StaticCastSharedPtr<STrackHead>(TrackGroupInstance.Head)->TrackData.TrackType == ETrackType::PlayerTrack)
if (TrackGroup.GroupType == ETrackType::PlayerTrack)
{
TSharedPtr<SPlayerLight> PlayerLight = SNew(SPlayerLight).Name(TrackGroupInstance.GroupName).TrackHead(TrackGroupInstance.Head);
(bSingle ? StatePanel->PlayerList1 : StatePanel->PlayerList2)->AddSlot()
[
PlayerLight.ToSharedRef()
];
bSingle = !bSingle;
PlayerLightsSlateInstances.Add(PlayerLight);
int32 i = 0;
FString LastGroupName;
for (FSingleTrackGroupInstance& TrackGroupInstance : CutTimeline->TrackGroupInstances)
{
if (LastGroupName != TrackGroupInstance.GroupName)
i = 0;
if (TrackGroupInstance.GroupName == TrackGroup.GroupName && StaticCastSharedPtr<STrackHead>(TrackGroupInstance.GetHead())->TrackData.TrackType == ETrackType::AtomSphereLightTrack)
{
LastGroupName = TrackGroupInstance.GroupName;
FString NewName = TrackGroupInstance.GroupName + FString::FromInt(i);
TSharedPtr<SPlayerLight> PlayerLight = SNew(SPlayerLight).Name(NewName).TrackHead(TrackGroupInstance.Head);
(bSingle ? StatePanel->PlayerList1 : StatePanel->PlayerList2)->AddSlot()
[
PlayerLight.ToSharedRef()
];
bSingle = !bSingle;
PlayerLightsSlateInstances.Add(PlayerLight);
}
i++;
}
}
}
}
@ -820,5 +838,14 @@ void SCutMainWindow::ClearProperties()
CustomPanel->UpdateProperties(nullptr);
}
void SCutMainWindow::DeleteAllAssetsInTimeline()
{
for (int32 i = 0; i < CutTimeline->TrackGroupInstances.Num(); i++)
{
CutTimeline->TrackGroupInstances[i].Body->DeleteUseLessClips();
}
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

View File

@ -70,6 +70,6 @@ public:
virtual FString GetGroupName(TSharedPtr<IWidgetInterface> WidgetInterface) override;
virtual void UpdateProperties(IPropertiesInterface* Interface) override;
virtual void ClearProperties() override;
virtual void DeleteAllAssetsInTimeline() override;
virtual SCutTimeline* GetCutTimeline() override { return CutTimeline.Get(); };
};

View File

@ -143,8 +143,25 @@ void SCutTimeline::Construct(const FArguments& InArgs)
SNew(SImage)
.Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("PlayButton.png"), {}))
]
+ SHorizontalBox::Slot()
.SizeParam(FStretch(1.0))
[
SNew(SSlider)
.Value(0.0f)
.OnValueChanged_Lambda([this](float ChangedValue)
{
TrackBodyHScrollBox->SetScrollOffset(ChangedValue * TrackBodyHScrollBox->GetScrollOffsetOfEnd());
TickScrollBox->SetScrollOffset(ChangedValue * TickScrollBox->GetScrollOffsetOfEnd());
FGlobalData::CurrentTimeScroll = ChangedValue;
})
]
+ SHorizontalBox::Slot()
.SizeParam(FAuto())
[
SAssignNew(CurrentEditDebug, STextBlock)
.Text(FText::FromString(TEXT("当前正在编辑主面板")))
]
]
]
@ -155,7 +172,7 @@ void SCutTimeline::Construct(const FArguments& InArgs)
// Timeline
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.SizeParam(FStretch(0.015f))
.SizeParam(FStretch(0.02f))
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
@ -239,27 +256,10 @@ void SCutTimeline::Construct(const FArguments& InArgs)
})
]
]
+ SVerticalBox::Slot()
.SizeParam(FAuto())
[
SNew(SSlider)
.Value(0.0f)
.OnValueChanged_Lambda([this](float ChangedValue)
{
TrackBodyHScrollBox->SetScrollOffset(ChangedValue * TrackBodyHScrollBox->GetScrollOffsetOfEnd());
TickScrollBox->SetScrollOffset(ChangedValue * TickScrollBox->GetScrollOffsetOfEnd());
FGlobalData::CurrentTimeScroll = ChangedValue;
})
]
]
]
+ SVerticalBox::Slot()
.SizeParam(FAuto())
[
SAssignNew(CurrentEditDebug, STextBlock)
.Text(FText::FromString(TEXT("当前正在编辑主面板")))
]
+ SVerticalBox::Slot()
.SizeParam(FAuto())
[
@ -363,13 +363,13 @@ TSharedPtr<SWidget> FSingleTrackGroupInstance::GetBody() const
void SCutTimeline::AddNewTrack(FTrackData TrackData, int32 TrackIndex, FString GroupName)
{
const TSharedPtr<STrackHead> NewTrackHead = SNew(STrackHead).TrackData(TrackData).CutTimeline(SharedThis(this)).MainWidgetInterface(MainWidgetInterface);
const TSharedPtr<STrackHead> NewTrackHead = SNew(STrackHead).TrackData(TrackData).CutTimeline(SharedThis(this)).MainWidgetInterface(MainWidgetInterface).GroupName(GroupName);
const TSharedPtr<STrackBody> NewTrackBody = SNew(STrackBody).TrackHead(NewTrackHead).MainWidgetInterface(MainWidgetInterface);
NewTrackBody->CallRender();
TrackGroupInstances.Add(FSingleTrackGroupInstance(NewTrackHead, NewTrackBody, GroupName));
}
void SCutTimeline::AddNewTrackToGroup(FString GroupName, FTrackData TrackData)
void SCutTimeline::AddNewTrackToGroup(FString GroupName, FTrackData TrackData, ETrackType GroupType)
{
bool bHasGroup = false;
for (FTrackGroup& Group : TrackGroups)
@ -386,11 +386,12 @@ void SCutTimeline::AddNewTrackToGroup(FString GroupName, FTrackData TrackData)
// Add New Group
FTrackGroup NewGroup(GroupName);
NewGroup.TrackDataArray.Add(TrackData);
NewGroup.GroupType = GroupType;
TrackGroups.Add(NewGroup);
}
AddNewTrack(TrackData, 0, GroupName);
RenderGroup();
MainWidgetInterface->OnAddNewTrack(TrackData.TrackType);
MainWidgetInterface->OnAddNewTrack(GroupType);
}
@ -416,6 +417,7 @@ void SCutTimeline::OnGroupNameEdited(FString NewText, FString OldText)
if (TSharedPtr<STrackHead> Head = StaticCastSharedPtr<STrackHead>(SingleTrackGroupInstance.Head))
{
Head->GroupName = NewText;
if (Head->TrackData.TrackType == ETrackType::PlayerTrack)
{
Head->TrackData.TrackName = NewText;
@ -424,6 +426,7 @@ void SCutTimeline::OnGroupNameEdited(FString NewText, FString OldText)
}
}
MainWidgetInterface->OnAddNewTrack(ETrackType::PlayerTrack);
RenderGroup();
}
@ -443,7 +446,7 @@ void SCutTimeline::RenderGroup()
SNew(SBox)
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
.HeightOverride(FGlobalData::DefaultTrackHeight * TrackGroups[i].TrackDataArray.Num())
.HeightOverride(FGlobalData::DefaultTrackHeight * (TrackGroups[i].GroupIsCollapsed ? 1 : TrackGroups[i].TrackDataArray.Num()))
.WidthOverride(24)
[
SNew(SOverlay)
@ -466,15 +469,43 @@ void SCutTimeline::RenderGroup()
OnGroupNameEdited(NewText.ToString(), TrackGroups[i].GroupName);
})
]
+ SOverlay::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Bottom)
.Padding(0, 0, 0, 4)
[
SNew(SImage)
.OnMouseButtonDown_Lambda([this, i](const FGeometry& Geometry, const FPointerEvent& MouseEvent)
{
if (TrackGroups[i].TrackDataArray.Num() > 1)
{
TrackGroups[i].GroupIsCollapsed = !TrackGroups[i].GroupIsCollapsed;
RenderGroup();
}
return FReply::Handled();
})
.Image(TrackGroups[i].GroupIsCollapsed ? FUtils::GetBrushFromImage(FUtils::GetResourcesPath(TEXT("Expaned.png")), {32, 16}) : FUtils::GetBrushFromImage(FUtils::GetResourcesPath(TEXT("Collapse.png")), {32, 16}))
]
]
];
// Add Instances to Group
int32 TrackIndex = 0;
FString LastGroupName;
for (FSingleTrackGroupInstance SingleTrackGroupInstance : TrackGroupInstances)
{
if (LastGroupName != TrackGroups[i].GroupName)
{
TrackIndex = 0;
}
if (SingleTrackGroupInstance.GroupName == TrackGroups[i].GroupName)
{
LastGroupName = SingleTrackGroupInstance.GroupName;
if (TrackGroups[i].GroupIsCollapsed == true && TrackIndex > 0)
{
TrackIndex++;
continue;
}
TrackHeadScrollBox->AddSlot()
[
SingleTrackGroupInstance.GetHead().ToSharedRef()
@ -484,6 +515,7 @@ void SCutTimeline::RenderGroup()
SingleTrackGroupInstance.GetBody().ToSharedRef()
];
}
TrackIndex++;
}
}

View File

@ -23,6 +23,8 @@ struct FTrackGroup
GroupName = InGroupName;
}
FString GroupName = "";
ETrackType GroupType = ETrackType::None;
bool GroupIsCollapsed = false;
TArray<FTrackData> TrackDataArray;
};
@ -38,6 +40,7 @@ struct FSingleTrackGroupInstance
TSharedPtr<SWidget> GetHead() const;
TSharedPtr<SWidget> GetBody() const;
FString GroupName;
TSharedPtr<IWidgetInterface> Head;
TSharedPtr<IWidgetInterface> Body;
};
@ -60,7 +63,7 @@ public:
void Construct(const FArguments& InArgs);
virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;
float TimeSpace = 0.0f;
void AddNewTrackToGroup(FString GroupName, FTrackData TrackData);
void AddNewTrackToGroup(FString GroupName, FTrackData TrackData, ETrackType GroupType = ETrackType::None);
void SetAutoPlay(bool bStart);
bool AutoPlaying = false;

View File

@ -18,8 +18,17 @@ void SPlayerLight::Construct(const FArguments& InArgs)
[
SNew(SScaleBox)
[
SAssignNew(PlayerLightImage, SImage)
.Image(SlateDynamicImageBrush)
SNew(SVerticalBox)
+ SVerticalBox::Slot()
[
SAssignNew(PlayerLightImage, SImage)
.Image(SlateDynamicImageBrush)
]
+ SVerticalBox::Slot()
[
SNew(STextBlock)
.Text(FText::FromString(Name))
]
]
];

View File

@ -7,13 +7,16 @@
#include "AudioDevice.h"
#include "SCutTimeline.h"
#include "SlateOptMacros.h"
#include "Commands/TimelineClipCommands.h"
#include "Cut5/WidgetInterface.h"
#include "Cut5/Utils/Utils.h"
#include "DragDropOperator/DragDropOperator.h"
#include "Engine/Engine.h"
#include "Engine/Texture2D.h"
#include "Presets/SClipCursor.h"
#include "Rendering/DrawElementPayloads.h"
#include "Slate/Private/Framework/Application/Menu.h"
extern "C"
@ -43,18 +46,20 @@ FReply STimelineClip::OnBorderMouseButtonDown(const FGeometry& Geometry, const F
}
MainWidgetInterface->SelectClip(ClipData->ClipGuid);
if (ClipData->PresetType != EPresetType::NotAPresets)
{
for (int32 i = 0; i < ClipData->Cursors.Num(); i++)
{
TSharedPtr<SClipCursor> ClipCursor = SNew(SClipCursor);
ClipOverlay->AddSlot()
[
ClipCursor.ToSharedRef()
];
}
}
// if (ClipData->PresetType != EPresetType::NotAPresets)
// {
// for (int32 i = 0; i < ClipData->Cursors.Num(); i++)
// {
// TSharedPtr<SClipCursor> ClipCursor = SNew(SClipCursor).CursorData(&ClipData->Cursors[i]); // .RenderTransform(FSlateRenderTransform(FVector2D(0, 0)));
// ClipOverlay->AddSlot()
// .HAlign(HAlign_Left)
// .VAlign(VAlign_Center)
// [
// ClipCursor.ToSharedRef()
// ];
// }
// }
const FVector2D LocalPos = Geometry.AbsoluteToLocal(PointerEvent.GetScreenSpacePosition());
if (LocalPos.X <= 10)
@ -97,6 +102,7 @@ void STimelineClip::Construct(const FArguments& InArgs)
MainWidgetInterface = InArgs._MainWidgetInterface;
Body = InArgs._Body;
SetRenderTransform(FSlateRenderTransform(FVector2D(ClipData->ClipStartFrame * FGlobalData::DefaultTimeTickSpace, 0)));
TSharedPtr<SClipCursor> ClipCursor = SNew(SClipCursor).RenderTransform(FSlateRenderTransform(FVector2D(0, 0)));
ChildSlot
[
SAssignNew(ClipDataBox, SBox)
@ -113,13 +119,30 @@ void STimelineClip::Construct(const FArguments& InArgs)
.BorderBackgroundColor(ClipData->ClipColors[0])
.OnMouseButtonDown(this, &STimelineClip::OnBorderMouseButtonDown)
]
]
];
if (ClipData->ClipType == ETrackType::AudioTrack)
{
}
if (MainWidgetInterface->GetCutTimeline()->SelectedClipGUID == ClipData->ClipGuid)
{
for (int32 i = 0; i < ClipData->Cursors.Num(); i++)
{
TSharedPtr<SClipCursor> NewClipCursor = SNew(SClipCursor).CursorData(&ClipData->Cursors[i])
.TimelineClip(this)
.ClipData(ClipData).RenderTransform(FSlateRenderTransform(FVector2D(ClipData->Cursors[i].CursorFrameOffset * FGlobalData::DefaultTimeTickSpace - 11, 0)));
ClipOverlay->AddSlot()
.HAlign(HAlign_Left)
.VAlign(VAlign_Center)
[
NewClipCursor.ToSharedRef()
];
}
}
}
void STimelineClip::Seek(int32 Frame)
@ -253,7 +276,17 @@ void STimelineClip::Seek(int32 Frame)
}
break;
case ETrackType::AtomSphereLightTrack:
{
const int32 Offset = Frame - ClipData->ClipStartFrame;
const int32 SeekMovieFrame = ClipData->VideoStartFrame + Offset;
if (SeekMovieFrame < ClipData->PlayerLightData.Num())
{
MainWidgetInterface->OnUpdatePlayers(Body, ClipData->PlayerLightData[SeekMovieFrame]);
}
break;
}
default:
break;
}
@ -266,6 +299,7 @@ void STimelineClip::UpdatePosition(int32 StartFrame)
return;
}
const int32 NewPosX = StartFrame * FGlobalData::DefaultTimeTickSpace;
GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::FromInt(NewPosX));
SetRenderTransform(FSlateRenderTransform(FVector2D(NewPosX, 0)));
ClipDataBox->SetWidthOverride((ClipData->ClipEndFrame - StartFrame) * FGlobalData::DefaultTimeTickSpace);
if (ClipData->ClipType == ETrackType::VideoTrack)
@ -273,6 +307,7 @@ void STimelineClip::UpdatePosition(int32 StartFrame)
ClipData->VideoStartFrame += StartFrame - ClipData->ClipStartFrame;
}
ClipData->ClipStartFrame = StartFrame;
GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::FromInt(ClipData->ClipStartFrame));
}
void STimelineClip::UpdateLength(int32 EndFrame)
@ -283,6 +318,7 @@ void STimelineClip::UpdateLength(int32 EndFrame)
ClipData->VideoEndFrame += EndFrame - ClipData->ClipEndFrame;
}
ClipData->ClipEndFrame = EndFrame;
GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::FromInt(ClipData->ClipEndFrame));
}
void STimelineClip::UpdateMove(int32 X, int32 DragOffset)
@ -293,6 +329,7 @@ void STimelineClip::UpdateMove(int32 X, int32 DragOffset)
ClipDataBox->SetWidthOverride(Length * FGlobalData::DefaultTimeTickSpace);
SetRenderTransform(FSlateRenderTransform(FVector2D(ClipData->ClipStartFrame * FGlobalData::DefaultTimeTickSpace, 0)));
}
@ -307,12 +344,33 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe
FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle,
bool bParentEnabled) const
{
const FSlateBrush Brush;
FSlateDrawElement::MakeBox(OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(),
&Brush, ESlateDrawEffect::None, FColor(0.5, 0.3, 0.1, 1.0));
// const FSlateBrush Brush;
// FSlateDrawElement::MakeBox(OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(),
// &Brush, ESlateDrawEffect::None, FColor(0.5, 0.3, 0.1, 1.0));
if (ClipData->PresetType == EPresetType::Gradient)
{
TArray<FSlateGradientStop> GradientStops;
for (int32 i = 0; i < ClipData->Cursors.Num(); i++)
{
GradientStops.Add(FSlateGradientStop(FVector2D(ClipData->Cursors[i].CursorFrameOffset * FGlobalData::DefaultTimeTickSpace, 0), ClipData->Cursors[i].Color));
}
FSlateDrawElement::MakeGradient(OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(),
GradientStops,
EOrientation::Orient_Vertical, ESlateDrawEffect::None);
}
return SCompoundWidget::OnPaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle,
bParentEnabled);
}
FReply STimelineClip::OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent)
{
DragDropOperator* DragDropOperation = DragDropOperator::GetDragDropOperator();
DragDropOperation->OnDragOver(MyGeometry, DragDropEvent);
return SCompoundWidget::OnDragOver(MyGeometry, DragDropEvent);
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

View File

@ -51,7 +51,7 @@ public:
int64 LastTimeStamp = 0;
virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override;
PaStream* Stream = nullptr;
virtual FReply OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override;
TSharedPtr<SOverlay> ClipOverlay;
TSharedPtr<FUICommandList> CommandList;

View File

@ -12,6 +12,7 @@ void STimelineProperty::Construct(const FArguments& InArgs)
{
TimelinePropertyData = InArgs._TimelinePropertyData;
MainWindow = InArgs._MainWindow;
MainInterface = InArgs._MainInterface;
ChildSlot
[
SNew(SBox)
@ -56,10 +57,13 @@ FReply STimelineProperty::OnMouseButtonDown(const FGeometry& MyGeometry, const F
FReply STimelineProperty::OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
UE_LOG(LogTemp, Warning, TEXT("On Drag Detected"));
const TSharedPtr<FTrackClipDragOperation> Operation = MakeShared<FTrackClipDragOperation>();
Operation->TimelinePropertyData = &TimelinePropertyData;
const TSharedPtr<FDeviceDragDrop> Operation = MakeShared<FDeviceDragDrop>();
// Operation->TimelinePropertyData = &TimelinePropertyData;
Operation->DraggingWidget = SharedThis(this);
Operation->DragDropType = FCutDragDropBase::EType::TrackClip;
Operation->DragDropType = FCutDragDropBase::EType::Device;
Operation->MainInterface = MainInterface;
Operation->DeviceName = TimelinePropertyData.Name;
Operation->TrackType = TimelinePropertyData.Type;
return FReply::Handled().BeginDragDrop(Operation.ToSharedRef());
}

View File

@ -20,12 +20,14 @@ public:
}
SLATE_ARGUMENT(FTimelinePropertyData, TimelinePropertyData)
SLATE_ARGUMENT(TSharedPtr<SCutMainWindow>, MainWindow)
SLATE_ARGUMENT(ICutMainWidgetInterface*, MainInterface)
SLATE_END_ARGS()
/** Constructs this widget with InArgs */
void Construct(const FArguments& InArgs);
FTimelinePropertyData TimelinePropertyData;
TSharedPtr<SCutMainWindow> MainWindow;
ICutMainWidgetInterface* MainInterface;
virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual FReply OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
};

View File

@ -12,6 +12,7 @@ BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void STimelinePropertyPanel::Construct(const FArguments& InArgs)
{
MainInterface = InArgs._MainInterface;
MainWindow = InArgs._MainWindow;
ChildSlot
[
@ -81,8 +82,8 @@ void STimelinePropertyPanel::Construct(const FArguments& InArgs)
{
return FReply::Handled();
}
const FTrackData PlayerData(TEXT("玩家"), ETrackType::PlayerTrack);
MainWindow->CutTimeline->AddNewTrackToGroup(TEXT("未命名"), PlayerData);
const FTrackData PlayerData(TEXT("玩家"), ETrackType::AtomSphereLightTrack);
MainWindow->CutTimeline->AddNewTrackToGroup(TEXT("未命名"), PlayerData, ETrackType::PlayerTrack);
return FReply::Handled();
})
]
@ -111,6 +112,7 @@ void STimelinePropertyPanel::AddNewSelection(FTimelinePropertyData TimelinePrope
SNew(STimelineProperty)
.TimelinePropertyData(TimelinePropertyData)
.MainWindow(MainWindow)
.MainInterface(MainInterface)
];
}

View File

@ -17,6 +17,7 @@ public:
{
}
SLATE_ARGUMENT(TSharedPtr<SCutMainWindow>, MainWindow)
SLATE_ARGUMENT(ICutMainWidgetInterface*, MainInterface)
SLATE_END_ARGS()
/** Constructs this widget with InArgs */
@ -25,9 +26,11 @@ public:
void AddNewSelection(FTimelinePropertyData TimelinePropertyData);
virtual FReply OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override;
ICutMainWidgetInterface* MainInterface;
private:
int32 MaxRowIndex = 3;
TSharedPtr<SCutMainWindow> MainWindow;
TSharedPtr<SGridPanel> GridPanel;
};

View File

@ -162,4 +162,15 @@ void STrackBody::Seek(int32 Frame)
}
}
void STrackBody::DeleteUseLessClips()
{
for (int32 i = 0; i < TrackHead->TrackData.ClipData.Num(); i++)
{
if (!TrackHead->TrackData.ClipData[i].ResourcePropertyDataPtr->bIsValid)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("DeleteUseLessClips"));
}
}
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

View File

@ -44,6 +44,6 @@ public:
TrackBodyBox->SetWidthOverride(FGlobalData::TrackLength * FGlobalData::DefaultTimeTickSpace);
};
virtual void Seek(int32 Frame) override;
virtual void DeleteUseLessClips() override;
TSharedPtr<FUICommandList> CommandList;
};

View File

@ -12,7 +12,7 @@ void STrackHead::Construct(const FArguments& InArgs)
TrackData = InArgs._TrackData;
CutTimeline = InArgs._CutTimeline;
MainWidgetInterface = InArgs._MainWidgetInterface;
GroupName = InArgs._GroupName;
TSharedPtr<SImage> Image = SNew(SImage);
ChildSlot
[

View File

@ -17,6 +17,7 @@ public:
{
}
SLATE_ARGUMENT(FTrackData, TrackData);
SLATE_ARGUMENT(FString, GroupName);
SLATE_ARGUMENT(TSharedPtr<SCutTimeline>, CutTimeline);
SLATE_ARGUMENT(ICutMainWidgetInterface*, MainWidgetInterface);
SLATE_END_ARGS()
@ -27,6 +28,6 @@ public:
FTrackData TrackData;
TSharedPtr<SCutTimeline> CutTimeline;
ICutMainWidgetInterface* MainWidgetInterface;
FString GroupName;
virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
};