From 84feb73412c36c722ecf2ae27d2a9ad44c49e8b9 Mon Sep 17 00:00:00 2001 From: Sch <3516520171@qq.com> Date: Thu, 17 Aug 2023 03:31:22 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BD=A8=E9=81=93=E7=A7=BB=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/Cut5/Utils/FFMPEGUtils.cpp | 10 +- Source/Cut5/Utils/Utils.cpp | 22 +++ Source/Cut5/Utils/Utils.h | 2 + Source/Cut5/Widgets/DefineGlobal.h | 10 +- .../DragDropOperator/DragDropOperator.cpp | 159 ++++++++++++------ .../DragDropOperator/DragDropOperator.h | 5 + Source/Cut5/Widgets/SCustomInputPanel.cpp | 5 +- Source/Cut5/Widgets/SCutMainWindow.cpp | 8 +- Source/Cut5/Widgets/STimelineClip.cpp | 4 + Source/Cut5/Widgets/STrackBody.cpp | 2 +- 10 files changed, 165 insertions(+), 62 deletions(-) diff --git a/Source/Cut5/Utils/FFMPEGUtils.cpp b/Source/Cut5/Utils/FFMPEGUtils.cpp index 55b94e8..bc22246 100644 --- a/Source/Cut5/Utils/FFMPEGUtils.cpp +++ b/Source/Cut5/Utils/FFMPEGUtils.cpp @@ -9,11 +9,11 @@ FString FFFMPEGUtils::LoadMedia(const FString& Path, FTimelinePropertyData* Prop AVFormatContext* FormatContext = nullptr; if (avformat_open_input(&FormatContext, TCHAR_TO_UTF8(*Path), nullptr, nullptr) != 0) { - check(false) + return TEXT("Failed"); } if (avformat_find_stream_info(FormatContext, nullptr) < 0) { - check(false) + return TEXT("Failed"); } PropertyData->MovieFrameLength = FormatContext->duration / AV_TIME_BASE * 30; int32 VideoStream = -1; @@ -37,7 +37,7 @@ FString FFFMPEGUtils::LoadMedia(const FString& Path, FTimelinePropertyData* Prop if (avcodec_open2(VideoCodecContext, VideoCodec, nullptr) < 0) { - check(false) + return TEXT("Failed"); } PropertyData->VideoCodec = VideoCodec; PropertyData->VideoCodecContext = VideoCodecContext; @@ -104,7 +104,7 @@ FString FFFMPEGUtils::LoadMedia(const FString& Path, FTimelinePropertyData* Prop AVCodec* AudioCodec = avcodec_find_decoder(AudioCodecContext->codec_id); if (avcodec_open2(AudioCodecContext, AudioCodec, nullptr) < 0) { - check(false) + return TEXT("Failed"); } TArray DataResult; @@ -167,7 +167,7 @@ FString FFFMPEGUtils::ConvertMediaGoPto1(const FString& Path) AVFormatContext* FormatContext = nullptr; if (avformat_open_input(&FormatContext, TCHAR_TO_UTF8(*Path), nullptr, nullptr) != 0) { - check(false) + return TEXT("Failed"); } int32 VideoStream = -1; int32 AudioStream = -1; diff --git a/Source/Cut5/Utils/Utils.cpp b/Source/Cut5/Utils/Utils.cpp index a79e6ea..36f3057 100644 --- a/Source/Cut5/Utils/Utils.cpp +++ b/Source/Cut5/Utils/Utils.cpp @@ -86,6 +86,27 @@ FSlateDynamicImageBrush* FUtils::GetBrushFromImage(const FString& ImageName, con return Brush; } + +bool FUtils::DetectDragTypeCanDrop(const FClipData& DraggingType, const ETrackType& DropTrackType) +{ + if (DropTrackType == ETrackType::LightArrayTrack || DropTrackType == ETrackType::LightBarTrack || DropTrackType == ETrackType::SpotLightTrack || DropTrackType == ETrackType::AtomSphereLightTrack) + { + ETrackType DraggingTrackType = DraggingType.ClipType; + // 支持预设灯光 + if (DraggingTrackType == ETrackType::LightArrayTrack || DraggingTrackType == ETrackType::LightBarTrack || DraggingTrackType == ETrackType::SpotLightTrack || DraggingTrackType == ETrackType::AtomSphereLightTrack) + { + return true; + } + } + + return false; + + + + + +} + void FUtils::CreateDefaultTimelineSave(const FString& SavedPath, const FTimelineInfo::ETimelineType Type) { TArray SavedData; @@ -519,3 +540,4 @@ FSaveModifier::~FSaveModifier() } FFileHelper::SaveArrayToFile(SavedData, *FullSavedPath); } + diff --git a/Source/Cut5/Utils/Utils.h b/Source/Cut5/Utils/Utils.h index 1349c71..5f6b50c 100644 --- a/Source/Cut5/Utils/Utils.h +++ b/Source/Cut5/Utils/Utils.h @@ -15,6 +15,8 @@ public: static FSlateDynamicImageBrush* GetBrushFromImage(const FString& ImageName, const FVector2D Size); static TArray BrushPtr; + + static bool DetectDragTypeCanDrop(const FClipData& DraggingType, const ETrackType& DropTrackType); /** * @brief Create a default timeline save file. * @param SavedPath Where to save. diff --git a/Source/Cut5/Widgets/DefineGlobal.h b/Source/Cut5/Widgets/DefineGlobal.h index 98a4768..da3a917 100644 --- a/Source/Cut5/Widgets/DefineGlobal.h +++ b/Source/Cut5/Widgets/DefineGlobal.h @@ -361,6 +361,12 @@ struct CUT5_API FClipData // Cursor TArray Cursors; EPresetType PresetType = EPresetType::NotAPresets; + + + bool operator == (const FClipData& Other) const + { + return ClipGuid == Other.ClipGuid; + } }; struct CUT5_API FTimelinePropertyData { @@ -494,6 +500,7 @@ public: Move, }; EDragType DragType; + TSharedPtr TrackBody; }; @@ -821,4 +828,5 @@ struct FEncodeVideoInfo FString EncodedVideoTimeCode = "00:00:00:00"; int32 ClipStartFrame = 0; int32 ClipEndFrame = 0; -}; \ No newline at end of file +}; + diff --git a/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp b/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp index ad1567a..a93c80c 100644 --- a/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp +++ b/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp @@ -1,6 +1,7 @@ #include "DragDropOperator.h" #include "Cut5/Utils/OpencvUtils.h" +#include "Cut5/Utils/Utils.h" #include "Cut5/Widgets/DefineGlobal.h" #include "Cut5/Widgets/SCutMainWindow.h" #include "Cut5/Widgets/STimelineClip.h" @@ -18,6 +19,79 @@ DragDropOperator* DragDropOperator::GetDragDropOperator() } return DragDropOperator::Operator; } +void DragDropOperator::UpdateClipProcess(ICutMainWidgetInterface* MainInterface, FClipData& TimelineClip) +{ + if (!MainInterface) + return; + + for (FSingleTrackGroupInstance& SingleTrackGroupInstance : MainInterface->GetCutTimeline()->TrackGroupInstances) + { + TSharedPtr TrackHead = StaticCastSharedPtr(SingleTrackGroupInstance.Head); + + + for (int32 i = TrackHead->TrackData.ClipData.Num() - 1; i >= 0; i--) + { + if (TimelineClip.ClipStartFrame == TrackHead->TrackData.ClipData[i].ClipStartFrame || TimelineClip.ClipEndFrame == TrackHead->TrackData.ClipData[i].ClipEndFrame) + { + continue; + } + const double ClipStartFrame = TrackHead->TrackData.ClipData[i].ClipStartFrame; + const double ClipEndFrame = TrackHead->TrackData.ClipData[i].ClipEndFrame; + + if (TimelineClip.ClipStartFrame >= ClipStartFrame && TimelineClip.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 = TimelineClip.ClipStartFrame; + TrackHead->TrackData.ClipData.Add(LeftClipData); + + FClipData RightClipData = SaveClipData; + RightClipData.ClipStartFrame = TimelineClip.ClipEndFrame; + TrackHead->TrackData.ClipData.Add(RightClipData); + + + continue; + } + if (TimelineClip.ClipStartFrame <= ClipEndFrame && TimelineClip.ClipEndFrame >= ClipEndFrame) + { + // It mean the new clip start point is in the old clip + int32 NewStartFrame = TimelineClip.ClipStartFrame; + int32 LeftCropFrame = TrackHead->TrackData.ClipData[i].ClipEndFrame - NewStartFrame; + TrackHead->TrackData.ClipData[i].CropClip(FClipData::ECropMethod::FromBack, LeftCropFrame); + continue; + } + if (TimelineClip.ClipEndFrame > ClipStartFrame && TimelineClip.ClipStartFrame < ClipStartFrame) + { + // It mean the new clip end point is in the old clip + TrackHead->TrackData.ClipData[i].CropClip(FClipData::ECropMethod::FromFront, (TimelineClip.ClipEndFrame - ClipStartFrame)); + continue; + } + if (TimelineClip.ClipStartFrame <= ClipStartFrame && TimelineClip.ClipEndFrame >= ClipEndFrame) + { + // It mean the new clip is out of the old clip + TrackHead->TrackData.ClipData.RemoveAt(i); + continue; + } + // const int32 CropFrameRight = TrackHead->TrackData.ClipData[i].GetClipRelativeEndFrame() - SelectedClipFrame - 1; + // TrackHead->TrackData.ClipData[i].CropClip(FClipData::ECropMethod::FromBack, CropFrameRight); + // + // NewClipData.CropClip(FClipData::ECropMethod::FromFront, SelectedClipFrame + 1); + // TrackHead->TrackData.ClipData.Add(NewClipData); + } + + + } + return; + +} + + + + void DragDropOperator::OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) { @@ -26,18 +100,28 @@ void DragDropOperator::OnDragOver(const FGeometry& MyGeometry, const FDragDropEv if (DragDropBase->DragDropType == FCutDragDropBase::EType::MovePanel) { TSharedPtr CutTimeline = StaticCastSharedPtr(DragDropBase->DraggingWidget); - float ChangedValue = (CutTimeline->GetCachedGeometry().AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X - DragDropEvent.GetOperationAs()->DragOffset); // / TrackBodyHScrollBox->GetScrollOffsetOfEnd(); + float Current = CutTimeline->GetCachedGeometry().AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X; + float DragOffset = DragDropEvent.GetOperationAs()->DragOffset; + float ChangedValue = (Current - DragOffset); + + if (CutTimeline->TrackBodyHScrollBox->GetScrollOffset() < 0) + { + CutTimeline->TrackBodyHScrollBox->SetScrollOffset(0); + CutTimeline->TickScrollBox->SetScrollOffset(0); + DragDropEvent.GetOperationAs()->DragOffset = 0; + } + if (CutTimeline->TrackBodyHScrollBox->GetScrollOffset() <= CutTimeline->TrackBodyHScrollBox->GetScrollOffsetOfEnd() - 10.0) { CutTimeline->TrackBodyHScrollBox->SetScrollOffset(CutTimeline->TrackBodyHScrollBox->GetScrollOffset() - ChangedValue); CutTimeline->TickScrollBox->SetScrollOffset(CutTimeline->TrackBodyHScrollBox->GetScrollOffset()); DragDropEvent.GetOperationAs()->DragOffset = (CutTimeline->GetCachedGeometry().AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X); - GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("ChangedValue: %f"), CutTimeline->TrackBodyHScrollBox->GetScrollOffset())); } else { - CutTimeline->TickScrollBox->SetScrollOffset(CutTimeline->TrackBodyHScrollBox->GetScrollOffsetOfEnd() - 11.0); + CutTimeline->TrackBodyHScrollBox->SetScrollOffset(CutTimeline->TrackBodyHScrollBox->GetScrollOffsetOfEnd() - 10.0); + CutTimeline->TickScrollBox->SetScrollOffset(CutTimeline->TickScrollBox->GetScrollOffsetOfEnd() - 10.0); DragDropEvent.GetOperationAs()->DragOffset = (CutTimeline->GetCachedGeometry().AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X); } return; @@ -428,59 +512,30 @@ void DragDropOperator::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& TSharedPtr TimelineClip = StaticCastSharedPtr(ClipDragOperation.DraggingWidget); TSharedPtr TrackHead = StaticCastSharedPtr(ClipDragOperation.OverrideWidget)->TrackHead; static_cast(TrackHead->MainWidgetInterface)->bRenderLine = false; - for (int32 i = TrackHead->TrackData.ClipData.Num() - 1; i >= 0; i--) + TSharedPtr TrackBody = StaticCastSharedPtr(ClipDragOperation.TrackBody); + + + + if (TrackBody != DropWidget) { - if (TimelineClip->ClipData->ClipStartFrame == TrackHead->TrackData.ClipData[i].ClipStartFrame || TimelineClip->ClipData->ClipEndFrame == TrackHead->TrackData.ClipData[i].ClipEndFrame) + + // It mean the clip is not in the same track + FClipData NewClipData = *TimelineClip->ClipData; + if (FUtils::DetectDragTypeCanDrop(NewClipData, TrackHead->TrackData.TrackType) == false) { - continue; + return; } - const double ClipStartFrame = TrackHead->TrackData.ClipData[i].ClipStartFrame; - const double ClipEndFrame = TrackHead->TrackData.ClipData[i].ClipEndFrame; - - if (TimelineClip->ClipData->ClipStartFrame >= ClipStartFrame && TimelineClip->ClipData->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 = TimelineClip->ClipData->ClipStartFrame; - TrackHead->TrackData.ClipData.Add(LeftClipData); - - FClipData RightClipData = SaveClipData; - RightClipData.ClipStartFrame = TimelineClip->ClipData->ClipEndFrame; - TrackHead->TrackData.ClipData.Add(RightClipData); - - - continue; - } - if (TimelineClip->ClipData->ClipStartFrame <= ClipEndFrame && TimelineClip->ClipData->ClipEndFrame >= ClipEndFrame) - { - // It mean the new clip start point is in the old clip - int32 NewStartFrame = TimelineClip->ClipData->ClipStartFrame; - int32 LeftCropFrame = TrackHead->TrackData.ClipData[i].ClipEndFrame - NewStartFrame; - TrackHead->TrackData.ClipData[i].CropClip(FClipData::ECropMethod::FromBack, LeftCropFrame); - continue; - } - if (TimelineClip->ClipData->ClipEndFrame > ClipStartFrame && TimelineClip->ClipData->ClipStartFrame < ClipStartFrame) - { - // It mean the new clip end point is in the old clip - TrackHead->TrackData.ClipData[i].CropClip(FClipData::ECropMethod::FromFront, (TimelineClip->ClipData->ClipEndFrame - ClipStartFrame)); - continue; - } - if (TimelineClip->ClipData->ClipStartFrame <= ClipStartFrame && TimelineClip->ClipData->ClipEndFrame >= ClipEndFrame) - { - // It mean the new clip is out of the old clip - TrackHead->TrackData.ClipData.RemoveAt(i); - continue; - } - // const int32 CropFrameRight = TrackHead->TrackData.ClipData[i].GetClipRelativeEndFrame() - SelectedClipFrame - 1; - // TrackHead->TrackData.ClipData[i].CropClip(FClipData::ECropMethod::FromBack, CropFrameRight); - // - // NewClipData.CropClip(FClipData::ECropMethod::FromFront, SelectedClipFrame + 1); - // TrackHead->TrackData.ClipData.Add(NewClipData); + + TSharedPtr OriginTrackBody = StaticCastSharedPtr(TimelineClip->Body); + OriginTrackBody->TrackHead->TrackData.ClipData.Remove(NewClipData); + TrackHead->TrackData.ClipData.Add(NewClipData); + UpdateClipProcess(TrackBody->MainWidgetInterface, NewClipData); + TrackBody->CallRender(); + + return; } + + UpdateClipProcess(TrackBody->MainWidgetInterface, *TimelineClip->ClipData); } } diff --git a/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.h b/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.h index e138fe8..dfd3873 100644 --- a/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.h +++ b/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.h @@ -1,4 +1,6 @@ #pragma once +#include "Cut5/Interface/CutMainWidgetInterface.h" + class DragDropOperator { @@ -10,4 +12,7 @@ public: void OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent); void OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent, TSharedPtr DropWidget); void OnDropAddNewTrack(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent, TSharedPtr DropWidget); + void UpdateClipProcess(ICutMainWidgetInterface* MainInterface, FClipData& TimelineClip); }; + + diff --git a/Source/Cut5/Widgets/SCustomInputPanel.cpp b/Source/Cut5/Widgets/SCustomInputPanel.cpp index 5e0aa3d..fd7d825 100644 --- a/Source/Cut5/Widgets/SCustomInputPanel.cpp +++ b/Source/Cut5/Widgets/SCustomInputPanel.cpp @@ -287,7 +287,10 @@ void SCustomInputPanel::Construct(const FArguments& InArgs) else { FTimelinePropertyData Data; - FFFMPEGUtils::LoadMedia(OpenFileName[i], &Data); + if (FFFMPEGUtils::LoadMedia(OpenFileName[i], &Data) == TEXT("Failed")) + { + return FReply::Handled(); + }; TSharedPtr Resource = SNew(SCustomInputResource) .PropertyData(Data).OnCheckBoxChecked_Lambda([this](FTimelinePropertyData& ClickedData, bool bIsChecked) diff --git a/Source/Cut5/Widgets/SCutMainWindow.cpp b/Source/Cut5/Widgets/SCutMainWindow.cpp index 4d868fe..f225acc 100644 --- a/Source/Cut5/Widgets/SCutMainWindow.cpp +++ b/Source/Cut5/Widgets/SCutMainWindow.cpp @@ -1069,11 +1069,15 @@ void SCutMainWindow::AddNewCustomPreset(const FString& Name, const FPresetsCusto FTimelinePropertyData NewPropertyData; NewPropertyData.bIsCustomPresetData = true; NewPropertyData.PresetsCustomData = CustomData; - + + TSharedPtr CustomInputResource = SNew(SCustomInputResource).PropertyData(NewPropertyData).CustomPresetName(Name); CustomInputPanel->GridPanel->AddSlot(CustomInputPanel->GridPanel->GetChildren()->Num() % 2, CustomInputPanel->GridPanel->GetChildren()->Num() / 2) [ - SNew(SCustomInputResource).PropertyData(NewPropertyData).CustomPresetName(Name) + CustomInputResource.ToSharedRef() ]; + + CustomInputPanel->ResourceInst.Add(CustomInputResource); + CustomInputPanel->PropertyData.Add(NewPropertyData); } tinyxml2::XMLElement* SCutMainWindow::GetDeviceElement(tinyxml2::XMLElement* Parent) diff --git a/Source/Cut5/Widgets/STimelineClip.cpp b/Source/Cut5/Widgets/STimelineClip.cpp index 498c096..6f8c7ca 100644 --- a/Source/Cut5/Widgets/STimelineClip.cpp +++ b/Source/Cut5/Widgets/STimelineClip.cpp @@ -9,6 +9,7 @@ #include "AudioDevice.h" #include "SCutTimeline.h" #include "SlateOptMacros.h" +#include "STrackBody.h" #include "Commands/TimelineClipCommands.h" #include "Cut5/WidgetInterface.h" #include "Cut5/Interface/SoundInterface.h" @@ -67,6 +68,7 @@ FReply STimelineClip::OnBorderMouseButtonDown(const FGeometry& Geometry, const F if (ClipData->bCanDrag) { const TSharedPtr Clip2ClipDragDropOperation = MakeShared(); + Clip2ClipDragDropOperation->TrackBody = StaticCastSharedPtr(Body); Clip2ClipDragDropOperation->DraggingWidget = SharedThis(this); Clip2ClipDragDropOperation->DragDropType = FCutDragDropBase::EType::Clip2Clip; Clip2ClipDragDropOperation->DragType = FClip2ClipDragDropOperation::EDragType::DragLeft; @@ -81,6 +83,7 @@ FReply STimelineClip::OnBorderMouseButtonDown(const FGeometry& Geometry, const F if (ClipData->bCanDrag) { const TSharedPtr Clip2ClipDragDropOperation = MakeShared(); + Clip2ClipDragDropOperation->TrackBody = StaticCastSharedPtr(Body); Clip2ClipDragDropOperation->DraggingWidget = SharedThis(this); Clip2ClipDragDropOperation->DragDropType = FCutDragDropBase::EType::Clip2Clip; Clip2ClipDragDropOperation->DragType = FClip2ClipDragDropOperation::EDragType::DragRight; @@ -92,6 +95,7 @@ FReply STimelineClip::OnBorderMouseButtonDown(const FGeometry& Geometry, const F else { const TSharedPtr Clip2ClipDragDropOperation = MakeShared(); + Clip2ClipDragDropOperation->TrackBody = StaticCastSharedPtr(Body); Clip2ClipDragDropOperation->DraggingWidget = SharedThis(this); Clip2ClipDragDropOperation->DragDropType = FCutDragDropBase::EType::Clip2Clip; Clip2ClipDragDropOperation->DragType = FClip2ClipDragDropOperation::EDragType::Move; diff --git a/Source/Cut5/Widgets/STrackBody.cpp b/Source/Cut5/Widgets/STrackBody.cpp index 7295923..4bd0d2d 100644 --- a/Source/Cut5/Widgets/STrackBody.cpp +++ b/Source/Cut5/Widgets/STrackBody.cpp @@ -124,7 +124,7 @@ FReply STrackBody::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointer { TSharedPtr DragDropOperator = MakeShared(); DragDropOperator->DragDropType = FCutDragDropBase::EType::MovePanel; - DragDropOperator->DragOffset = MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()).X; + DragDropOperator->DragOffset = MainWidgetInterface->GetCutTimeline()->GetCachedGeometry().AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()).X; DragDropOperator->DraggingWidget = TrackHead->CutTimeline; return FReply::Handled().DetectDrag(SharedThis(this), EKeys::LeftMouseButton).BeginDragDrop(DragDropOperator.ToSharedRef()); }