diff --git a/Cut5.uproject b/Cut5.uproject index c537ab8..a23ec9b 100644 --- a/Cut5.uproject +++ b/Cut5.uproject @@ -20,6 +20,10 @@ "TargetAllowList": [ "Editor" ] + }, + { + "Name": "OpenCV", + "Enabled": true } ] } \ No newline at end of file diff --git a/Source/Cut5/Cut5.Build.cs b/Source/Cut5/Cut5.Build.cs index 3c7e7fa..c58ee1d 100644 --- a/Source/Cut5/Cut5.Build.cs +++ b/Source/Cut5/Cut5.Build.cs @@ -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"); diff --git a/Source/Cut5/Widgets/DefineGlobal.h b/Source/Cut5/Widgets/DefineGlobal.h index e1afa6f..3304cff 100644 --- a/Source/Cut5/Widgets/DefineGlobal.h +++ b/Source/Cut5/Widgets/DefineGlobal.h @@ -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,9 +31,17 @@ struct CUT5_API FClipData { FGuid ClipGuid; ETrackType ClipType; - int32 ClipStartFrame = 0; - int32 ClipEndFrame = 10; + double ClipStartTime = 0; + double ClipEndTime = 10; TArray 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 diff --git a/Source/Cut5/Widgets/SCutMainWindow.cpp b/Source/Cut5/Widgets/SCutMainWindow.cpp index 02ab102..c66e30d 100644 --- a/Source/Cut5/Widgets/SCutMainWindow.cpp +++ b/Source/Cut5/Widgets/SCutMainWindow.cpp @@ -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 diff --git a/Source/Cut5/Widgets/SCutMainWindow.h b/Source/Cut5/Widgets/SCutMainWindow.h index 84d82e1..f42ada5 100644 --- a/Source/Cut5/Widgets/SCutMainWindow.h +++ b/Source/Cut5/Widgets/SCutMainWindow.h @@ -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 CutTimeline; - + TSharedPtr LightArrayPanel; + TSharedPtr VideoPlayer; + virtual FReply OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override; virtual FReply OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override; + + }; diff --git a/Source/Cut5/Widgets/SCutTimeline.cpp b/Source/Cut5/Widgets/SCutTimeline.cpp index bd3bf87..a36f952 100644 --- a/Source/Cut5/Widgets/SCutTimeline.cpp +++ b/Source/Cut5/Widgets/SCutTimeline.cpp @@ -49,6 +49,7 @@ int32 SCutTimeline::GetCursorPosition() const void SCutTimeline::Construct(const FArguments& InArgs) { + ChildSlot [ SNew(SVerticalBox) diff --git a/Source/Cut5/Widgets/SCutTimeline.h b/Source/Cut5/Widgets/SCutTimeline.h index f6ff254..1c979d3 100644 --- a/Source/Cut5/Widgets/SCutTimeline.h +++ b/Source/Cut5/Widgets/SCutTimeline.h @@ -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(); diff --git a/Source/Cut5/Widgets/SLightArrayPanel.cpp b/Source/Cut5/Widgets/SLightArrayPanel.cpp new file mode 100644 index 0000000..0d342fe --- /dev/null +++ b/Source/Cut5/Widgets/SLightArrayPanel.cpp @@ -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 diff --git a/Source/Cut5/Widgets/SLightArrayPanel.h b/Source/Cut5/Widgets/SLightArrayPanel.h new file mode 100644 index 0000000..332fd56 --- /dev/null +++ b/Source/Cut5/Widgets/SLightArrayPanel.h @@ -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 LightGrid; +}; diff --git a/Source/Cut5/Widgets/STimelineClip.cpp b/Source/Cut5/Widgets/STimelineClip.cpp index cba0958..bf7ec5a 100644 --- a/Source/Cut5/Widgets/STimelineClip.cpp +++ b/Source/Cut5/Widgets/STimelineClip.cpp @@ -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 diff --git a/Source/Cut5/Widgets/STimelineClip.h b/Source/Cut5/Widgets/STimelineClip.h index 501e191..794aee4 100644 --- a/Source/Cut5/Widgets/STimelineClip.h +++ b/Source/Cut5/Widgets/STimelineClip.h @@ -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(); }; + diff --git a/Source/Cut5/Widgets/STrackBody.cpp b/Source/Cut5/Widgets/STrackBody.cpp index b2f4e16..83156b2 100644 --- a/Source/Cut5/Widgets/STrackBody.cpp +++ b/Source/Cut5/Widgets/STrackBody.cpp @@ -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 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> 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 diff --git a/Source/Cut5/Widgets/STrackBody.h b/Source/Cut5/Widgets/STrackBody.h index ae068f8..5f32b09 100644 --- a/Source/Cut5/Widgets/STrackBody.h +++ b/Source/Cut5/Widgets/STrackBody.h @@ -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 TrackHead; TSharedPtr Overlay; TSharedPtr TrackBodyBox; - + TArray> SlateClips; // Interface virtual void UpdateTimelineLength() override { diff --git a/Source/Cut5/Widgets/SVideoPlayer.cpp b/Source/Cut5/Widgets/SVideoPlayer.cpp new file mode 100644 index 0000000..635f907 --- /dev/null +++ b/Source/Cut5/Widgets/SVideoPlayer.cpp @@ -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 diff --git a/Source/Cut5/Widgets/SVideoPlayer.h b/Source/Cut5/Widgets/SVideoPlayer.h new file mode 100644 index 0000000..8426bf3 --- /dev/null +++ b/Source/Cut5/Widgets/SVideoPlayer.h @@ -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 VideoImage; +};