This commit is contained in:
Sch 2023-07-03 17:28:11 +08:00
parent 2e6d6e6915
commit 440945e67b
15 changed files with 258 additions and 44 deletions

View File

@ -20,6 +20,10 @@
"TargetAllowList": [
"Editor"
]
},
{
"Name": "OpenCV",
"Enabled": true
}
]
}

View File

@ -13,7 +13,7 @@ public class Cut5 : ModuleRules
PrivateDependencyModuleNames.AddRange(new string[] { });
PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore", "UMG"});
PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore", "UMG", "OpenCV"});
// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem");

View File

@ -7,6 +7,8 @@ public:
inline static int32 DefaultTrackHeight = 50;
inline static int32 TrackLength = 1000;
inline static double DefaultTimeTickSpace = 10.0;
inline static int32 LightArrayX = 70;
inline static int32 LightArrayY = 42;
};
enum class ETrackType
{
@ -29,10 +31,18 @@ struct CUT5_API FClipData
{
FGuid ClipGuid;
ETrackType ClipType;
int32 ClipStartFrame = 0;
int32 ClipEndFrame = 10;
double ClipStartTime = 0;
double ClipEndTime = 10;
TArray<FLinearColor> ClipColors;
int32 GetClipStartFrame() const { return ClipStartTime / FGlobalData::DefaultTimeTickSpace; };
int32 GetClipEndFrame() const { return ClipEndTime / FGlobalData::DefaultTimeTickSpace; };
// Movies
FString MoviePath;
int32 VideoStartFrame = 0;
int32 VideoEndFrame = 0;
};
struct CUT5_API FTimelinePropertyData
{

View File

@ -8,12 +8,15 @@
#include "STimelinePropertyPanel.h"
#include "Widgets/Layout/SConstraintCanvas.h"
#include "Widgets/Layout/SScaleBox.h"
#include "Widgets/Views/STreeView.h"
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SCutMainWindow::Construct(const FArguments& InArgs)
{
SAssignNew(CutTimeline, SCutTimeline);
SAssignNew(LightArrayPanel, SLightArrayPanel);
SAssignNew(VideoPlayer, SVideoPlayer);
ChildSlot
[
SNew(SScaleBox)
@ -34,6 +37,16 @@ void SCutMainWindow::Construct(const FArguments& InArgs)
+ SHorizontalBox::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
[
VideoPlayer.ToSharedRef()
]
]
+ SHorizontalBox::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
@ -44,15 +57,16 @@ void SCutMainWindow::Construct(const FArguments& InArgs)
]
]
+ SHorizontalBox::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
[
LightArrayPanel.ToSharedRef()
]
]
+ SHorizontalBox::Slot()
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
]
]
+ SVerticalBox::Slot()
.HAlign(HAlign_Fill)
@ -102,4 +116,5 @@ FReply SCutMainWindow::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent&
return FReply::Handled().EndDragDrop();
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

View File

@ -4,6 +4,8 @@
#include "CoreMinimal.h"
#include "SCutTimeline.h"
#include "SLightArrayPanel.h"
#include "SVideoPlayer.h"
#include "Widgets/SCompoundWidget.h"
/**
@ -22,7 +24,11 @@ public:
void Construct(const FArguments& InArgs);
TSharedPtr<SCutTimeline> CutTimeline;
TSharedPtr<SLightArrayPanel> LightArrayPanel;
TSharedPtr<SVideoPlayer> VideoPlayer;
virtual FReply OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override;
virtual FReply OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override;
};

View File

@ -49,6 +49,7 @@ int32 SCutTimeline::GetCursorPosition() const
void SCutTimeline::Construct(const FArguments& InArgs)
{
ChildSlot
[
SNew(SVerticalBox)

View File

@ -4,9 +4,9 @@
#include "CoreMinimal.h"
#include "DefineGlobal.h"
#include "STimelineTick.h"
#include "Cut5/WidgetInterface.h"
#include "Widgets/SCompoundWidget.h"
#include "Widgets/Layout/SScrollBox.h"
@ -24,7 +24,6 @@ public:
SLATE_BEGIN_ARGS(SCutTimeline)
{
}
SLATE_END_ARGS()
void UpdateTimelineLength();

View File

@ -0,0 +1,57 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "SLightArrayPanel.h"
#include "DefineGlobal.h"
#include "SlateOptMacros.h"
#include "Widgets/Layout/SGridPanel.h"
#include "Widgets/Layout/SScaleBox.h"
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SLightArrayPanel::Construct(const FArguments& InArgs)
{
ChildSlot
[
SNew(SScaleBox)
[
SNew(SBox)
.WidthOverride(500)
.HeightOverride(400)
[
SAssignNew(LightGrid, SGridPanel)
]
]
];
GenerateLightArray();
}
void SLightArrayPanel::GenerateLightArray()
{
for (int32 i = 0; i < FGlobalData::LightArrayX; i++)
{
for (int32 j = 0; j < FGlobalData::LightArrayY; j++)
{
LightGrid->AddSlot(i, j)
[
SNew(SBox)
[
SNew(SBorder)
.ColorAndOpacity(FLinearColor(1, 1, 0, 1))
]
];
}
}
}
void SLightArrayPanel::UpdateLightArray(int32 X, int32 Y, FLinearColor Color)
{
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

View File

@ -0,0 +1,26 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"
#include "Widgets/Layout/SGridPanel.h"
/**
*
*/
class CUT5_API SLightArrayPanel : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(SLightArrayPanel)
{
}
SLATE_END_ARGS()
/** Constructs this widget with InArgs */
void Construct(const FArguments& InArgs);
void GenerateLightArray();
void UpdateLightArray(int32 X, int32 Y, FLinearColor Color);
TSharedPtr<SGridPanel> LightGrid;
};

View File

@ -9,12 +9,34 @@ BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void STimelineClip::Construct(const FArguments& InArgs)
{
/*
ClipData = InArgs._InClipData;
ChildSlot
[
// Populate the widget
SNew(SBox)
.WidthOverride(ClipData.ClipEndTime - ClipData.ClipStartTime)
.HeightOverride(FGlobalData::DefaultTrackHeight)
.RenderTransform(FSlateRenderTransform(FVector2D(ClipData.ClipStartTime, 0)))
[
SNew(SBorder)
.ColorAndOpacity(ClipData.ClipColors[0])
.BorderBackgroundColor(ClipData.ClipColors[0])
]
];
*/
}
void STimelineClip::Seek()
{
switch (ClipData.ClipType)
{
case ETrackType::VideoTrack:
break;
default:
break;
}
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

View File

@ -15,11 +15,12 @@ public:
SLATE_BEGIN_ARGS(STimelineClip)
{
}
SLATE_ARGUMENT(FClipData, InClipData)
SLATE_END_ARGS()
/** Constructs this widget with InArgs */
void Construct(const FArguments& InArgs);
FClipData ClipData;
virtual void Seek();
};

View File

@ -39,28 +39,23 @@ void STrackBody::Construct(const FArguments& InArgs)
void STrackBody::CallRender()
{
Overlay->ClearChildren();
for (FClipData TempClipData : TrackHead->TrackData.ClipData)
SlateClips.Empty();
for (const FClipData& TempClipData : TrackHead->TrackData.ClipData)
{
if (TempClipData.ClipEndFrame > FGlobalData::TrackLength)
if (TempClipData.ClipEndTime > FGlobalData::TrackLength)
{
FGlobalData::TrackLength = TempClipData.ClipEndFrame;
FGlobalData::TrackLength = TempClipData.ClipEndTime;
TrackHead->CutTimeline->UpdateTimelineLength();
}
TSharedPtr<STimelineClip> TimelineClip;
TimelineClip = SNew(STimelineClip).InClipData(TempClipData);
Overlay->AddSlot()
.HAlign(HAlign_Left)
[
SNew(SBox)
.WidthOverride(TempClipData.ClipEndFrame - TempClipData.ClipStartFrame)
.HeightOverride(FGlobalData::DefaultTrackHeight)
.RenderTransform(FSlateRenderTransform(FVector2D(TempClipData.ClipStartFrame, 0)))
[
SNew(SBorder)
.ColorAndOpacity(TempClipData.ClipColors[0])
.BorderBackgroundColor(TempClipData.ClipColors[0])
]
TimelineClip.ToSharedRef()
];
const FString A = FString::Printf(TEXT("%d"), TempClipData.ClipEndFrame - TempClipData.ClipStartFrame);
UE_LOG(LogTemp, Warning, TEXT("%s"), *A);
SlateClips.Add(TimelineClip);
}
}
@ -76,23 +71,37 @@ FReply STrackBody::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& Dra
FClipData NewClipData;
NewClipData.ClipGuid = FGuid::NewGuid();
NewClipData.ClipType = ClipDragOperation.TimelinePropertyData.Type;
NewClipData.ClipStartFrame = FMath::TruncToInt(MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X / FGlobalData::DefaultTimeTickSpace) * FGlobalData::DefaultTimeTickSpace;
NewClipData.ClipStartTime = FMath::TruncToInt(MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X / FGlobalData::DefaultTimeTickSpace) * FGlobalData::DefaultTimeTickSpace;
NewClipData.ClipColors.Add(FLinearColor(1, 1, 1, 1));;
NewClipData.ClipEndFrame = NewClipData.ClipStartFrame + 200;
NewClipData.ClipEndTime = NewClipData.ClipStartTime + 200;
//Overwrite the clip if it is in the same position
for (int32 i = TrackHead->TrackData.ClipData.Num() - 1; i > 0; i--)
TArray<int32, TInlineAllocator<2>> Indexes = {-1, -1};
for (int32 i = TrackHead->TrackData.ClipData.Num() - 1; i >= 0; i--)
{
const double ClipStartTime = TrackHead->TrackData.ClipData[i].ClipStartFrame;
const double ClipEndTime = TrackHead->TrackData.ClipData[i].ClipEndFrame;
if ((NewClipData.ClipEndFrame < ClipEndTime && ClipEndTime > ClipStartTime))
const double ClipStartTime = TrackHead->TrackData.ClipData[i].ClipStartTime;
const double ClipEndTime = TrackHead->TrackData.ClipData[i].ClipEndTime;
if (NewClipData.ClipEndTime < ClipEndTime && NewClipData.ClipEndTime > ClipStartTime)
{
TrackHead->TrackData.ClipData[i].ClipStartFrame = NewClipData.ClipEndFrame;
Indexes[0] = i;
}
if ((NewClipData.ClipStartFrame < TrackHead->TrackData.ClipData[i].ClipEndFrame && NewClipData.ClipStartFrame > TrackHead->TrackData.ClipData[i].ClipStartFrame))
if (NewClipData.ClipStartTime > ClipStartTime && NewClipData.ClipStartTime < ClipEndTime)
{
TrackHead->TrackData.ClipData[i].ClipEndFrame = NewClipData.ClipStartFrame;
Indexes[1] = i;
}
}
if (Indexes[0] != -1 && Indexes[1] == -1)
{
TrackHead->TrackData.ClipData[Indexes[0]].ClipStartTime = NewClipData.ClipEndTime;
}
if (Indexes[1] != -1 && Indexes[0] == -1)
{
TrackHead->TrackData.ClipData[Indexes[1]].ClipEndTime = NewClipData.ClipStartTime;
}
else
{
}
TrackHead->TrackData.ClipData.Add(NewClipData);
CallRender();
@ -103,9 +112,7 @@ FReply STrackBody::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& Dra
FReply STrackBody::OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent)
{
// GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Blue, DragDropEvent.GetScreenSpacePosition().ToString());
// GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Green, MyGeometry.GetAbsolutePosition().ToString());
// GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).ToString());
return SCompoundWidget::OnDragOver(MyGeometry, DragDropEvent);
}
@ -121,7 +128,14 @@ void STrackBody::OnDragLeave(const FDragDropEvent& DragDropEvent)
void STrackBody::Seek(int32 Frame)
{
for (int32 i = 0; i < SlateClips.Num(); i++)
{
if (SlateClips[i]->ClipData.GetClipStartFrame() <= Frame && SlateClips[i]->ClipData.GetClipEndFrame() > Frame)
{
SlateClips[i]->Seek();
break;
}
}
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

View File

@ -3,6 +3,7 @@
#pragma once
#include "CoreMinimal.h"
#include "STimelineClip.h"
#include "STrackHead.h"
#include "Widgets/SCompoundWidget.h"
@ -28,7 +29,7 @@ public:
TSharedPtr<STrackHead> TrackHead;
TSharedPtr<SOverlay> Overlay;
TSharedPtr<SBox> TrackBodyBox;
TArray<TSharedPtr<STimelineClip>> SlateClips;
// Interface
virtual void UpdateTimelineLength() override
{

View File

@ -0,0 +1,34 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "SVideoPlayer.h"
#include "SlateOptMacros.h"
#include "Widgets/Layout/SScaleBox.h"
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SVideoPlayer::Construct(const FArguments& InArgs)
{
ChildSlot
[
SNew(SScaleBox)
.Stretch(EStretch::ScaleToFit)
[
SNew(SBox)
.WidthOverride(1920)
.HeightOverride(1080)
[
SAssignNew(VideoImage, SImage)
]
]
];
}
void SVideoPlayer::UpdateVideoData(FGuid UUID, FLinearColor Color)
{
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

View File

@ -0,0 +1,24 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"
/**
*
*/
class CUT5_API SVideoPlayer : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(SVideoPlayer)
{
}
SLATE_END_ARGS()
/** Constructs this widget with InArgs */
void Construct(const FArguments& InArgs);
void UpdateVideoData(FGuid UUID, FLinearColor Color);
TSharedPtr<SImage> VideoImage;
};