diff --git a/Cut5.uproject b/Cut5.uproject index 46a4830..4a44a89 100644 --- a/Cut5.uproject +++ b/Cut5.uproject @@ -28,7 +28,10 @@ { "Name": "SoundUtilities", "Enabled": true + }, + { + "Name": "RiderSourceCodeAccess", + "Enabled": false } - ] } \ No newline at end of file diff --git a/Source/Cut5/Widgets/DefineGlobal.h b/Source/Cut5/Widgets/DefineGlobal.h index c12e3be..59094ab 100644 --- a/Source/Cut5/Widgets/DefineGlobal.h +++ b/Source/Cut5/Widgets/DefineGlobal.h @@ -32,6 +32,7 @@ public: inline static FString BasePath = FPaths::ProjectDir(); inline static FString Version = "1.0.0"; inline static FString ExportPath = ""; + inline static TArray Colors = { FColor(175, 93, 81, 255), @@ -96,6 +97,7 @@ enum class EPresetType Video, DisableProjector, EnableProjector, + Custom, // Use Preset Custom Data }; struct FClipData; @@ -165,16 +167,26 @@ struct CUT5_API FPresetsData struct CUT5_API FPresetsCustomData { - TArray Colors = { FLinearColor::White }; - int32 Times; + enum class EPresetCustomType + { + None, + Breathe, + Flash, + }; + + TArray Colors = { FLinearColor(1, 1 , 1) }; + int32 Times = 1; float Angle; - int32 Time; + float Time; + EPresetCustomType PresetCustomType = EPresetCustomType::None; + friend FArchive& operator<<(FArchive& Ar, FPresetsCustomData& PresetsData) { Ar << PresetsData.Colors; Ar << PresetsData.Times; Ar << PresetsData.Angle; Ar << PresetsData.Time; + Ar << PresetsData.PresetCustomType; return Ar; } }; @@ -200,6 +212,7 @@ struct CUT5_API FClipData Ar << ClipData.Cursors; Ar << ClipData.PresetType; Ar << ClipData.bCanDrag; + Ar << ClipData.PresetsCustomData; return Ar; }; @@ -223,7 +236,7 @@ struct CUT5_API FClipData int32 GetClipEndFrame() const { return ClipEndTime / FGlobalData::DefaultTimeTickSpace; }; int32 GetClipRelativeEndFrame() const { return ClipEndFrame - ClipStartFrame; } - + FPresetsCustomData PresetsCustomData; enum class ECropMethod { @@ -379,6 +392,7 @@ public: ColorDragH, ColorDragS, ColorDragV, + MovePanel, }; FCutDragDropBase() {}; FCutDragDropBase(EType InType) diff --git a/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp b/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp index 969ce15..285293e 100644 --- a/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp +++ b/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp @@ -23,6 +23,18 @@ void DragDropOperator::OnDragOver(const FGeometry& MyGeometry, const FDragDropEv { if (TSharedPtr DragDropBase = DragDropEvent.GetOperationAs()) { + if (DragDropBase->DragDropType == FCutDragDropBase::EType::MovePanel) + { + TSharedPtr CutTimeline = StaticCastSharedPtr(DragDropBase->DraggingWidget); + float ChangedValue = (MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X - DragDropEvent.GetOperationAs()->DragOffset); // / TrackBodyHScrollBox->GetScrollOffsetOfEnd(); + CutTimeline->TrackBodyHScrollBox->SetScrollOffset(CutTimeline->TrackBodyHScrollBox->GetScrollOffset() - ChangedValue); + CutTimeline->TickScrollBox->SetScrollOffset(CutTimeline->TickScrollBox->GetScrollOffset() - ChangedValue); + DragDropEvent.GetOperationAs()->DragOffset = (MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X); + FGlobalData::CurrentTimeScroll = ChangedValue; + return; + } + + if (DragDropBase->DragDropType == FCutDragDropBase::EType::ColorDragH || DragDropBase->DragDropType == FCutDragDropBase::EType::ColorDragV) { TSharedPtr ColorBar = StaticCastSharedPtr(DragDropBase->DraggingWidget); @@ -203,6 +215,7 @@ void DragDropOperator::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& FTrackData NewTrackData; NewTrackData.TrackType = CutDragDropBase->TrackType; NewTrackData.TrackName = CutDragDropBase->DeviceName; + CutDragDropBase->MainInterface->GetCutTimeline()->AddNewTrackToGroup(TrackHead->GroupName, NewTrackData); CutDragDropBase->MainInterface->OnAddNewTrack(ETrackType::PlayerTrack); return; @@ -216,76 +229,97 @@ void DragDropOperator::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& FTrackClipDragOperation& ClipDragOperation = *ClipDragOperationShared.Get(); if (!ClipDragOperationShared.IsValid()) return; - if (ClipDragOperation.TimelinePropertyData->Type != TrackHead->TrackData.TrackType) + + + FClipData NewClipData; + NewClipData.ClipGuid = FGuid::NewGuid(); + + ETrackType TrackType = TrackHead->TrackData.TrackType; + ETrackType ClipType = ClipDragOperation.TimelinePropertyData->Type; + float TrackDropFrame = MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X / FGlobalData::DefaultTimeTickSpace; + + // If custom preset + if (ClipDragOperation.TimelinePropertyData->bIsCustomPresetData) { - 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::VideoTrack && TrackHead->TrackData.TrackType == ETrackType::AtomSphereLightTrack)) - { - - } - else + if (TrackType == ETrackType::AudioTrack || TrackType == ETrackType::ProjectorTrack || TrackType == ETrackType::AudioTrackR) { return; } + NewClipData.PresetType = EPresetType::Custom; + NewClipData.PresetsCustomData = ClipDragOperation.TimelinePropertyData->PresetsCustomData; + NewClipData.ClipStartFrame = TrackDropFrame; + NewClipData.ClipEndFrame = NewClipData.ClipStartFrame + (float(NewClipData.PresetsCustomData.Time) * 30); + NewClipData.ClipType = TrackType; } - - - 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) + else { - // 如果拖拽物是视频,那么对不同轨道进行不同和操作 - NewClipData.MoviePath = ClipDragOperation.TimelinePropertyData->MoviePath; - NewClipData.ClipEndFrame = NewClipData.ClipStartFrame + ClipDragOperation.TimelinePropertyData->MovieFrameLength; - NewClipData.VideoEndFrame = ClipDragOperation.TimelinePropertyData->MovieFrameLength; - NewClipData.VideoCapture = ClipDragOperation.VideoCapture; - if (TrackHead->TrackData.TrackType == ETrackType::LightArrayTrack) + if (ClipDragOperation.TimelinePropertyData->Type != TrackHead->TrackData.TrackType) { - 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(TrackHead->MainWidgetInterface); - if (!MainWidget->CutTimeline->GetTrackGroupByName(TEXT("视频附着"))) + 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::VideoTrack && TrackHead->TrackData.TrackType == ETrackType::AtomSphereLightTrack)) { - MainWidget->CutTimeline->AddNewTrackToGroup(TEXT("视频附着"), FTrackData(TEXT("附着音频"), ETrackType::AudioTrack)); + } - + else + { + return; + } + } + NewClipData.ClipType = TrackHead->TrackData.TrackType; + NewClipData.ClipStartFrame = TrackDropFrame; + 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.VideoEndFrame = 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::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(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; } } - 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; - } + diff --git a/Source/Cut5/Widgets/MicroWidgets/SColorPanel.cpp b/Source/Cut5/Widgets/MicroWidgets/SColorPanel.cpp index 8353bdf..645aeb1 100644 --- a/Source/Cut5/Widgets/MicroWidgets/SColorPanel.cpp +++ b/Source/Cut5/Widgets/MicroWidgets/SColorPanel.cpp @@ -16,6 +16,12 @@ BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION void SColorPanel::Construct(const FArguments& InArgs) { ColorPtr = InArgs._ColorPtr; + + CurrentSelectColor = ColorPtr->LinearRGBToHSV(); + + ColorS = ColorPtr->LinearRGBToHSV().G; + + FTextBlockStyle TextBlockStyle = FAppStyle::GetWidgetStyle("NormalText"); TextBlockStyle.SetFontSize(16); ChildSlot @@ -71,7 +77,7 @@ void SColorPanel::Construct(const FArguments& InArgs) .ColorType(SColorBar::EColorType::V) .OnColorCallBack_Lambda([this](float A) { - + }) ] diff --git a/Source/Cut5/Widgets/Presets/SEffectPreset.cpp b/Source/Cut5/Widgets/Presets/SEffectPreset.cpp index 0070426..013ec01 100644 --- a/Source/Cut5/Widgets/Presets/SEffectPreset.cpp +++ b/Source/Cut5/Widgets/Presets/SEffectPreset.cpp @@ -11,6 +11,7 @@ #include "Widgets/Input/SComboBox.h" #include "Widgets/Input/SSpinBox.h" #include "Widgets/Input/NumericTypeInterface.h" +#include "Widgets/Layout/SSpacer.h" BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION @@ -76,6 +77,12 @@ void SEffectPreset::Construct(const FArguments& InArgs) TSharedPtr SEffectPreset::GetPropertiesWidget() { + Selectable.Empty(); + Selectable.Add(MakeShared(TEXT("无"))); + Selectable.Add(MakeShared(TEXT("呼吸"))); + Selectable.Add(MakeShared(TEXT("闪烁"))); + + FTextBlockStyle NormalText = FAppStyle::GetWidgetStyle("NormalText"); NormalText.SetFontSize(13); PropertiesWidget = @@ -152,6 +159,35 @@ TSharedPtr SEffectPreset::GetPropertiesWidget() .HeightOverride(32) [ SNew(SComboBox>) + .OptionsSource(&Selectable) + .OnGenerateWidget_Lambda([this](TSharedPtr InItem) + { + return SNew(STextBlock).Text(FText::FromString(*InItem)); + }) + .OnSelectionChanged_Lambda([this](TSharedPtr InItem, ESelectInfo::Type SelectInfo) + { + switch (Selectable.Find(InItem)) + { + case 0: + CustomData.PresetCustomType = FPresetsCustomData::EPresetCustomType::None; + break; + case 1: + CustomData.PresetCustomType = FPresetsCustomData::EPresetCustomType::Breathe; + break; + case 2: + CustomData.PresetCustomType = FPresetsCustomData::EPresetCustomType::Flash; + break; + default: + break; + } + }) + [ + SNew(STextBlock) + .Text_Lambda([this]() + { + return FText::FromString( CustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::None ? TEXT("无") : CustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::Breathe ? TEXT("呼吸") : TEXT("闪烁")); + }) + ] ] ] ] @@ -185,7 +221,8 @@ TSharedPtr SEffectPreset::GetPropertiesWidget() .HeightOverride(32) [ SNew(SSpinBox) - .MinValue(0) + .Value(1) + .MinValue(1) .OnValueChanged_Lambda([this](const int32& Value) { CustomData.Times = Value; @@ -196,46 +233,6 @@ TSharedPtr SEffectPreset::GetPropertiesWidget() ] + SVerticalBox::Slot() .Padding(0, 13, 0, 0) - [ - SNew(SBox).HeightOverride(32).WidthOverride(214) - [ - SNew(SHorizontalBox) - + SHorizontalBox::Slot() - .SizeParam(FAuto()) - .VAlign(VAlign_Center) - [ - SNew(SBox) - .WidthOverride(62) - .HeightOverride(32) - .VAlign(VAlign_Center) - [ - SNew(STextBlock) - .Text(FText::FromString(TEXT("角度"))) - .Font(NormalText.Font) - .Justification(ETextJustify::Center) - ] - ] - + SHorizontalBox::Slot() - .SizeParam(FAuto()) - [ - SNew(SBox) - .WidthOverride(136) - .HeightOverride(32) - [ - SNew(SSpinBox) - .MinValue(0.0) - .MaxValue(360.0) - .OnValueChanged_Lambda([this](const float& Value) - { - CustomData.Angle = Value; - }) - // .TypeInterface(MakeShared>(EUnit::Degrees)) - ] - ] - ] - ] - + SVerticalBox::Slot() - .Padding(0, 13, 0, 0) [ SNew(SBox).HeightOverride(32).WidthOverride(214) [ @@ -262,9 +259,10 @@ TSharedPtr SEffectPreset::GetPropertiesWidget() .WidthOverride(136) .HeightOverride(32) [ - SNew(SSpinBox) - .MinValue(0.0) - .OnValueChanged_Lambda([this](const int32& Value) + SNew(SSpinBox) + .Value(0.3) + .MinValue(0.3) + .OnValueChanged_Lambda([this](const float& Value) { CustomData.Time = Value; }) @@ -274,6 +272,11 @@ TSharedPtr SEffectPreset::GetPropertiesWidget() ] ] + SVerticalBox::Slot() + .SizeParam(FStretch(1.0)) + [ + SNew(SSpacer) + ] + + SVerticalBox::Slot() .HAlign(HAlign_Center) .VAlign(VAlign_Bottom) .Padding(0, 0, 0, 24) @@ -306,6 +309,7 @@ TSharedPtr SEffectPreset::GetPropertiesWidget() .Visibility(EVisibility::HitTestInvisible) .Text(FText::FromString((TEXT("保存自定义效果")))) .Font(NormalText.Font) + .Justification(ETextJustify::Center) ] ] ]; diff --git a/Source/Cut5/Widgets/Presets/SEffectPreset.h b/Source/Cut5/Widgets/Presets/SEffectPreset.h index 4124fcd..6501258 100644 --- a/Source/Cut5/Widgets/Presets/SEffectPreset.h +++ b/Source/Cut5/Widgets/Presets/SEffectPreset.h @@ -33,7 +33,7 @@ public: EPresetType PresetType; TSharedPtr>> GroupComboBox; virtual TSharedPtr GetPropertiesWidget() override; - - FPresetsCustomData CustomData; + TArray> Selectable; + FPresetsCustomData CustomData; virtual FReply OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; }; diff --git a/Source/Cut5/Widgets/SCutMainWindow.cpp b/Source/Cut5/Widgets/SCutMainWindow.cpp index 25703a9..0c7cf71 100644 --- a/Source/Cut5/Widgets/SCutMainWindow.cpp +++ b/Source/Cut5/Widgets/SCutMainWindow.cpp @@ -1040,7 +1040,46 @@ tinyxml2::XMLElement* SCutMainWindow::GetDeviceElement(tinyxml2::XMLElement* Par } tinyxml2::XMLElement* PlayerLightList = Light->InsertNewChildElement("PlayerLightList"); { - + int32 j = 0; + for (int32 i = 0; i < CutTimeline->TrackGroupInstances.Num(); i++) + { + const FTrackData& TrackData = StaticCastSharedPtr(CutTimeline->TrackGroupInstances[i].Head)->TrackData; + if (TrackData.TrackType == ETrackType::AtomSphereLightTrack) + { + tinyxml2::XMLElement* PlayerLight = PlayerLightList->InsertNewChildElement(TCHAR_TO_UTF8(*FString::Printf(TEXT("PlayerLight(%d)"), j))); + tinyxml2::XMLElement* SpeicalEffect = PlayerLight->InsertNewChildElement("Special_Effects_List"); + for (int32 k = 0; k < TrackData.ClipData.Num(); k++) + { + + const FClipData& TempClipData = TrackData.ClipData[k]; + if (TempClipData.PresetsCustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::Breathe) + { + tinyxml2::XMLElement* NewSpeicalEffect = SpeicalEffect->InsertNewChildElement("Special_Effect"); + NewSpeicalEffect->InsertNewChildElement("Mode")->InsertNewText("0"); + NewSpeicalEffect->InsertNewChildElement("InitialColor")->InsertNewText(TCHAR_TO_UTF8(*FString::Printf(TEXT("%ls"), *TempClipData.PresetsCustomData.Colors[0].ToFColor(false).ToHex()))); + NewSpeicalEffect->InsertNewChildElement("EndColor")->InsertNewText(TCHAR_TO_UTF8(*FString::Printf(TEXT("%ls"), *FLinearColor::Black.ToFColor(false).ToHex()))); + float PerLength = (TempClipData.PresetsCustomData.Time / TempClipData.PresetsCustomData.Times); + NewSpeicalEffect->InsertNewChildElement("TimeLength")->InsertNewText(TCHAR_TO_UTF8(*FString::Printf(TEXT("%d"), int32(PerLength * 1000)))); + NewSpeicalEffect->InsertNewChildElement("TimeCode")->InsertNewText(TCHAR_TO_UTF8(*FString::Printf(TEXT("%ls"), *FUtils::GetMsFromString(FGlobalData::GetTimeData(TempClipData.ClipStartFrame))))); + NewSpeicalEffect->InsertNewChildElement("Cycle")->InsertNewText(TCHAR_TO_UTF8(*FString::Printf(TEXT("%d"), TempClipData.PresetsCustomData.Times))); + } + if (TempClipData.PresetsCustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::Flash) + { + tinyxml2::XMLElement* NewSpeicalEffect = SpeicalEffect->InsertNewChildElement("Special_Effect"); + NewSpeicalEffect->InsertNewChildElement("Mode")->InsertNewText("0"); + NewSpeicalEffect->InsertNewChildElement("InitialColor")->InsertNewText(TCHAR_TO_UTF8(*FString::Printf(TEXT("%ls"), *TempClipData.PresetsCustomData.Colors[0].ToFColor(false).ToHex()))); + NewSpeicalEffect->InsertNewChildElement("EndColor")->InsertNewText(TCHAR_TO_UTF8(*FString::Printf(TEXT("%ls"), *TempClipData.PresetsCustomData.Colors[0].ToFColor(false).ToHex()))); + float PerLength = (TempClipData.PresetsCustomData.Time / TempClipData.PresetsCustomData.Times) / 2; + NewSpeicalEffect->InsertNewChildElement("TimeLength")->InsertNewText(TCHAR_TO_UTF8(*FString::Printf(TEXT("%d"), int32(PerLength * 1000)))); + NewSpeicalEffect->InsertNewChildElement("TimeCode")->InsertNewText(TCHAR_TO_UTF8(*FString::Printf(TEXT("%ls"), *FUtils::GetMsFromString(FGlobalData::GetTimeData(TempClipData.ClipStartFrame))))); + NewSpeicalEffect->InsertNewChildElement("Cycle")->InsertNewText(TCHAR_TO_UTF8(*FString::Printf(TEXT("%d"), TempClipData.PresetsCustomData.Times))); + } + } + j++; + } + } + + } tinyxml2::XMLElement* GuangZhenList = Light->InsertNewChildElement("GuangZhenList"); { diff --git a/Source/Cut5/Widgets/SCutTimeline.cpp b/Source/Cut5/Widgets/SCutTimeline.cpp index 9a6d15e..31fca95 100644 --- a/Source/Cut5/Widgets/SCutTimeline.cpp +++ b/Source/Cut5/Widgets/SCutTimeline.cpp @@ -18,6 +18,22 @@ BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION +FReply SCutTimeline::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) +{ + TSharedPtr DragDropOperator = MakeShared(); + DragDropOperator->DragDropType = FCutDragDropBase::EType::MovePanel; + DragDropOperator->DragOffset = MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()).X; + DragDropOperator->DraggingWidget = SharedThis(this); + return FReply::Handled().DetectDrag(SharedThis(this), EKeys::LeftMouseButton).BeginDragDrop(DragDropOperator.ToSharedRef()); +} + +FReply SCutTimeline::OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) +{ + DragDropOperator* DragDropOperator = DragDropOperator::GetDragDropOperator(); + DragDropOperator->OnDragOver(MyGeometry, DragDropEvent); + return SCompoundWidget::OnDragOver(MyGeometry, DragDropEvent); +} + void SCutTimeline::UpdateTimelineLength() { TimelineTickBox->SetWidthOverride(FGlobalData::TrackLength * FGlobalData::DefaultTimeTickSpace); @@ -34,7 +50,7 @@ void SCutTimeline::UpdateCursorPosition(int32 Frame) { if (Frame >= 0 && Frame <= FGlobalData::TrackLength) { - TimelineTick->UpdateNewCursorPosition(Frame * FGlobalData::DefaultTimeTickSpace); + TimelineTick->UpdateNewCursorPosition(Frame); MainWidgetInterface->PreSettingBeforeSeek(); for (const FSingleTrackGroupInstance& Interface : TrackGroupInstances) { @@ -156,9 +172,8 @@ void SCutTimeline::Construct(const FArguments& InArgs) .Value(0.0f) .OnValueChanged_Lambda([this](float ChangedValue) { - TrackBodyHScrollBox->SetScrollOffset(ChangedValue * TrackBodyHScrollBox->GetScrollOffsetOfEnd()); - TickScrollBox->SetScrollOffset(ChangedValue * TickScrollBox->GetScrollOffsetOfEnd()); - FGlobalData::CurrentTimeScroll = ChangedValue; + FGlobalData::DefaultTimeTickSpace = 1 + ChangedValue * 10; + RenderGroup(); }) ] + SHorizontalBox::Slot() @@ -447,6 +462,8 @@ void SCutTimeline::RenderGroup() TrackBodyScrollBox->ClearChildren(); FTextBlockStyle BlackHugeText = FAppStyle::GetWidgetStyle("NormalText"); BlackHugeText.SetFontSize(16); + + for (int32 i = 0; i < TrackGroups.Num(); i++) { @@ -517,6 +534,11 @@ void SCutTimeline::RenderGroup() TrackIndex++; continue; } + + // Update Instance Position + StaticCastSharedPtr(SingleTrackGroupInstance.GetBody())->CallRender(); + StaticCastSharedPtr(SingleTrackGroupInstance.GetBody())->TrackBodyBox->SetWidthOverride(FGlobalData::TrackLength * FGlobalData::DefaultTimeTickSpace); + TrackHeadScrollBox->AddSlot() [ SingleTrackGroupInstance.GetHead().ToSharedRef() diff --git a/Source/Cut5/Widgets/SCutTimeline.h b/Source/Cut5/Widgets/SCutTimeline.h index 3069413..81ecd88 100644 --- a/Source/Cut5/Widgets/SCutTimeline.h +++ b/Source/Cut5/Widgets/SCutTimeline.h @@ -55,7 +55,8 @@ public: } SLATE_ARGUMENT(ICutMainWidgetInterface*, MainWidgetInterface) SLATE_END_ARGS() - + virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; + virtual FReply OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override; void UpdateTimelineLength(); void UpdateCursorPosition(int32 Frame); int32 GetCursorPosition() const; diff --git a/Source/Cut5/Widgets/STimelineClip.cpp b/Source/Cut5/Widgets/STimelineClip.cpp index 061253a..24de3e1 100644 --- a/Source/Cut5/Widgets/STimelineClip.cpp +++ b/Source/Cut5/Widgets/STimelineClip.cpp @@ -272,6 +272,49 @@ void STimelineClip::Seek(int32 Frame) { const int32 Offset = Frame - ClipData->ClipStartFrame; const int32 SeekMovieFrame = ClipData->VideoStartFrame + Offset; + + if (ClipData->PresetsCustomData.PresetCustomType != FPresetsCustomData::EPresetCustomType::None) + { + if (ClipData->PresetsCustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::Breathe) + { + // 先拿到目前位置在第几个区间 + float Between = -1; + int32 SingleAreaLength = (ClipData->ClipEndFrame - ClipData->ClipStartFrame) / ClipData->PresetsCustomData.Times / 2; + if (SeekMovieFrame > 0) + { + Between = (float)SeekMovieFrame / (float)SingleAreaLength; + } + + if (Between != -1) + { + FLinearColor LinearColor = FLinearColor::Black; + FLinearColor CustomColor = ClipData->PresetsCustomData.Colors[0]; + LinearColor = FMath::Lerp((int32)Between % 2 == 0 ? CustomColor : FLinearColor::Black, (int32)Between % 2 == 0 ? FLinearColor::Black : CustomColor, Between - (int32)Between); + GEngine->AddOnScreenDebugMessage(-1, 0.1f, FColor::Red, FString::Printf(TEXT("Between %s"), *CustomColor.ToString())); + MainWidgetInterface->OnUpdateSpotLight(0, LinearColor.ToFColor(false)); + } + } + else if (ClipData->PresetsCustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::Flash) + { + float Between = -1; + int32 SingleAreaLength = (ClipData->ClipEndFrame - ClipData->ClipStartFrame) / ClipData->PresetsCustomData.Times / 2; + if (SeekMovieFrame > 0) + { + Between = (float)SeekMovieFrame / (float)SingleAreaLength; + } + + if (Between != -1) + { + MainWidgetInterface->OnUpdateSpotLight(0, (int32)Between % 2 == 1 ? ClipData->PresetsCustomData.Colors[0].ToFColor(false) : FLinearColor::Black.ToFColor(false)); + } + } + + + break; + } + + + if (ClipData->PresetType == EPresetType::NotAPresets) { if (SeekMovieFrame < ClipData->PlayerLightData.Num()) @@ -309,6 +352,52 @@ void STimelineClip::Seek(int32 Frame) const int32 Offset = Frame - ClipData->ClipStartFrame; const int32 SeekMovieFrame = ClipData->VideoStartFrame + Offset; + + if (ClipData->PresetsCustomData.PresetCustomType != FPresetsCustomData::EPresetCustomType::None) + { + if (ClipData->PresetsCustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::Breathe) + { + // 先拿到目前位置在第几个区间 + float Between = -1; + int32 SingleAreaLength = (ClipData->ClipEndFrame - ClipData->ClipStartFrame) / ClipData->PresetsCustomData.Times / 2; + if (SeekMovieFrame > 0) + { + Between = (float)SeekMovieFrame / (float)SingleAreaLength; + } + + if (Between != -1) + { + FLinearColor LinearColor = FLinearColor::Black; + FLinearColor CustomColor = ClipData->PresetsCustomData.Colors[0]; + LinearColor = FMath::Lerp((int32)Between % 2 == 0 ? CustomColor : FLinearColor::Black, (int32)Between % 2 == 0 ? FLinearColor::Black : CustomColor, Between - (int32)Between); + TArray Colors; + Colors.Init(LinearColor.ToFColor(false), FGlobalData::LightArrayX * FGlobalData::LightArrayY * 4); + MainWidgetInterface->OnUpdateLightArray(Colors); + } + } + else if (ClipData->PresetsCustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::Flash) + { + float Between = -1; + int32 SingleAreaLength = (ClipData->ClipEndFrame - ClipData->ClipStartFrame) / ClipData->PresetsCustomData.Times / 2; + if (SeekMovieFrame > 0) + { + Between = (float)SeekMovieFrame / (float)SingleAreaLength; + } + + if (Between != -1) + { + TArray Colors; + Colors.Init((int32)Between % 2 == 1 ? ClipData->PresetsCustomData.Colors[0].ToFColor(false) : FLinearColor::Black.ToFColor(false), FGlobalData::LightArrayX * FGlobalData::LightArrayY * 4); + MainWidgetInterface->OnUpdateLightArray(Colors); + + } + } + + + break; + } + + if (ClipData->PresetType == EPresetType::Color) { @@ -397,6 +486,47 @@ void STimelineClip::Seek(int32 Frame) { const int32 Offset = Frame - ClipData->ClipStartFrame; const int32 SeekMovieFrame = ClipData->VideoStartFrame + Offset; + if (ClipData->PresetsCustomData.PresetCustomType != FPresetsCustomData::EPresetCustomType::None) + { + if (ClipData->PresetsCustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::Breathe) + { + // 先拿到目前位置在第几个区间 + float Between = -1; + int32 SingleAreaLength = (ClipData->ClipEndFrame - ClipData->ClipStartFrame) / ClipData->PresetsCustomData.Times / 2; + if (SeekMovieFrame > 0) + { + Between = (float)SeekMovieFrame / (float)SingleAreaLength; + } + + if (Between != -1) + { + FLinearColor LinearColor = FLinearColor::Black; + FLinearColor CustomColor = ClipData->PresetsCustomData.Colors[0]; + LinearColor = FMath::Lerp((int32)Between % 2 == 0 ? CustomColor : FLinearColor::Black, (int32)Between % 2 == 0 ? FLinearColor::Black : CustomColor, Between - (int32)Between); + GEngine->AddOnScreenDebugMessage(-1, 0.1f, FColor::Red, FString::Printf(TEXT("Between %s"), *CustomColor.ToString())); + MainWidgetInterface->OnUpdatePlayers(Body, LinearColor.ToFColor(false)); + } + } + else if (ClipData->PresetsCustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::Flash) + { + float Between = -1; + int32 SingleAreaLength = (ClipData->ClipEndFrame - ClipData->ClipStartFrame) / ClipData->PresetsCustomData.Times / 2; + if (SeekMovieFrame > 0) + { + Between = (float)SeekMovieFrame / (float)SingleAreaLength; + } + + if (Between != -1) + { + MainWidgetInterface->OnUpdatePlayers(Body, (int32)Between % 2 == 1 ? ClipData->PresetsCustomData.Colors[0].ToFColor(false) : FLinearColor::Black.ToFColor(false)); + } + } + + + break; + } + + if (ClipData->PresetType == EPresetType::NotAPresets) { if (SeekMovieFrame < ClipData->PlayerLightData.Num()) @@ -520,6 +650,33 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe bool bParentEnabled) const { + TArray BreatheGradientStops; + if (ClipData->PresetsCustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::Breathe) + { + for (int32 i = 0; i < ClipData->PresetsCustomData.Times * 2; i++) + { + int32 CurrentSpace = i * (AllottedGeometry.Size.X / ClipData->PresetsCustomData.Times); + BreatheGradientStops.Add(FSlateGradientStop(FVector2f(CurrentSpace / 2, 0), i % 2 == 0 ? ClipData->PresetsCustomData.Colors[0] : FLinearColor::Black)); + } + BreatheGradientStops.Add(FSlateGradientStop(FVector2f(AllottedGeometry.Size.X, 0), ClipData->PresetsCustomData.Colors[0])); + FSlateDrawElement::MakeGradient(OutDrawElements, LayerId + 4, AllottedGeometry.ToPaintGeometry(), + BreatheGradientStops, + EOrientation::Orient_Vertical, ESlateDrawEffect::None); + return SCompoundWidget::OnPaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId + 1, InWidgetStyle, + bParentEnabled); + } + if (ClipData->PresetsCustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::Flash) + { + for (int32 i = 0; i < ClipData->PresetsCustomData.Times * 2; i++) + { + const FSlateBrush SlateBrush; + int32 CurrentSpace = i * (AllottedGeometry.Size.X / ClipData->PresetsCustomData.Times); + FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 4, AllottedGeometry.ToPaintGeometry(FVector2f((AllottedGeometry.Size.X / ClipData->PresetsCustomData.Times) / 2, AllottedGeometry.Size.Y), FSlateLayoutTransform(FVector2f(CurrentSpace / 2, 0))), + &SlateBrush, ESlateDrawEffect::None, i % 2 == 0 ? ClipData->PresetsCustomData.Colors[0] : FLinearColor::Black); + } + } + + if (ClipData->PresetType == EPresetType::Color) { const FSlateBrush Brush; @@ -535,7 +692,7 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe GradientStops.Add(FSlateGradientStop(FVector2D(ClipData->Cursors[i].CursorFrameOffset * FGlobalData::DefaultTimeTickSpace, 0), ClipData->Cursors[i].Color)); } - FSlateDrawElement::MakeGradient(OutDrawElements, LayerId + 10000, AllottedGeometry.ToPaintGeometry(), + FSlateDrawElement::MakeGradient(OutDrawElements, LayerId + 4, AllottedGeometry.ToPaintGeometry(), GradientStops, EOrientation::Orient_Vertical, ESlateDrawEffect::None); } diff --git a/Source/Cut5/Widgets/STimelineTick.cpp b/Source/Cut5/Widgets/STimelineTick.cpp index 8fc455a..f46a213 100644 --- a/Source/Cut5/Widgets/STimelineTick.cpp +++ b/Source/Cut5/Widgets/STimelineTick.cpp @@ -32,14 +32,14 @@ void STimelineTick::Construct(const FArguments& InArgs) } -void STimelineTick::UpdateNewCursorPosition(const float Position) +void STimelineTick::UpdateNewCursorPosition(const int32 Position) { const FSlateRenderTransform NewRenderTransform = - ::Concatenate(FScale2D(0.3, 38), FShear2D(0, 0), FQuat2D(FMath::DegreesToRadians(0)), FVector2D(Position, -2)); + ::Concatenate(FScale2D(0.3, 38), FShear2D(0, 0), FQuat2D(FMath::DegreesToRadians(0)), FVector2D(Position * FGlobalData::DefaultTimeTickSpace, -2)); if (TickCursor) { TickCursor->SetRenderTransform(NewRenderTransform); - CursorPosition = Position / FGlobalData::DefaultTimeTickSpace; + CursorPosition = Position; } } @@ -99,7 +99,7 @@ FReply STimelineTick::OnMouseButtonDown(const FGeometry& MyGeometry, const FPoin FReply STimelineTick::OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) { - UpdateNewCursorPosition((MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X)); + UpdateNewCursorPosition((MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X) / FGlobalData::DefaultTimeTickSpace); return SCompoundWidget::OnDragOver(MyGeometry, DragDropEvent); } diff --git a/Source/Cut5/Widgets/STimelineTick.h b/Source/Cut5/Widgets/STimelineTick.h index 7fae42e..f715794 100644 --- a/Source/Cut5/Widgets/STimelineTick.h +++ b/Source/Cut5/Widgets/STimelineTick.h @@ -21,7 +21,7 @@ public: /** Constructs this widget with InArgs */ void Construct(const FArguments& InArgs); - void UpdateNewCursorPosition(const float Position); + void UpdateNewCursorPosition(const int32 Position); void GenerateTickBox(int32 TickCount); virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override; int32 GetCursorPosition() const { return CursorPosition; }; diff --git a/Source/Cut5/Widgets/STrackBody.cpp b/Source/Cut5/Widgets/STrackBody.cpp index cbd85c5..930486d 100644 --- a/Source/Cut5/Widgets/STrackBody.cpp +++ b/Source/Cut5/Widgets/STrackBody.cpp @@ -103,6 +103,8 @@ FReply STrackBody::OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& { CutDragDropBase->OverrideWidget = SharedThis(this); } + // DragDropOperator* DragDropOperator = DragDropOperator::GetDragDropOperator(); + // DragDropOperator->OnDragOver(MyGeometry, DragDropEvent); return SCompoundWidget::OnDragOver(MyGeometry, DragDropEvent); } @@ -116,6 +118,15 @@ void STrackBody::OnDragLeave(const FDragDropEvent& DragDropEvent) SCompoundWidget::OnDragLeave(DragDropEvent); } +FReply STrackBody::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) +{ + TSharedPtr DragDropOperator = MakeShared(); + DragDropOperator->DragDropType = FCutDragDropBase::EType::MovePanel; + DragDropOperator->DragOffset = MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()).X; + DragDropOperator->DraggingWidget = TrackHead->CutTimeline; + return FReply::Handled().DetectDrag(SharedThis(this), EKeys::LeftMouseButton).BeginDragDrop(DragDropOperator.ToSharedRef()); +} + void STrackBody::RemoveClip(const FGuid& Guid) { for (int32 i = 0; i < SlateClips.Num(); i++) diff --git a/Source/Cut5/Widgets/STrackBody.h b/Source/Cut5/Widgets/STrackBody.h index de37a5e..37685a8 100644 --- a/Source/Cut5/Widgets/STrackBody.h +++ b/Source/Cut5/Widgets/STrackBody.h @@ -29,6 +29,7 @@ public: virtual FReply OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override; virtual void OnDragEnter(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override; virtual void OnDragLeave(const FDragDropEvent& DragDropEvent) override; + virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; virtual void RemoveClip(const FGuid& Guid) override; virtual void BreakClip(const FGuid& Guid) override;