diff --git a/Cut5.sln b/Cut5.sln index 6b74737..8e330d5 100644 --- a/Cut5.sln +++ b/Cut5.sln @@ -7,49 +7,67 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Engine", "Engine", "{233774 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Games", "Games", "{DE1F8B53-6C02-3C13-9101-A7C8D96F3FF6}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UE5", "Intermediate\ProjectFiles\UE5.vcxproj", "{6EE39883-7339-3FB6-AD82-931FB137D37F}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Cut5", "Intermediate\ProjectFiles\Cut5.vcxproj", "{B95E7D0E-DB45-3765-9058-E00EBBC4B157}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Cut5", "Intermediate\ProjectFiles\Cut5.vcxproj", "{AF5A253A-0F37-38CE-8998-45CA936C112B}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UE5", "Intermediate\ProjectFiles\UE5.vcxproj", "{C48D0E9D-C862-3EA3-96A7-752EE9D06362}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Visualizers", "Visualizers", "{1CCEC849-CC72-4C59-8C36-2F7C38706D4C}" ProjectSection(SolutionItems) = preProject - D:\UE\UE_5.2\Engine\Extras\VisualStudioDebugging\Unreal.natvis = D:\UE\UE_5.2\Engine\Extras\VisualStudioDebugging\Unreal.natvis + ..\..\Software\UE_5.2\Engine\Extras\VisualStudioDebugging\Unreal.natvis = ..\..\Software\UE_5.2\Engine\Extras\VisualStudioDebugging\Unreal.natvis EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + DebugGame Editor|Android = DebugGame Editor|Android DebugGame Editor|Win64 = DebugGame Editor|Win64 + DebugGame|Android = DebugGame|Android DebugGame|Win64 = DebugGame|Win64 + Development Editor|Android = Development Editor|Android Development Editor|Win64 = Development Editor|Win64 + Development|Android = Development|Android Development|Win64 = Development|Win64 + Shipping|Android = Shipping|Android Shipping|Win64 = Shipping|Win64 EndGlobalSection # UnrealVS Section GlobalSection(ddbf523f-7eb6-4887-bd51-85a714ff87eb) = preSolution - AvailablePlatforms=Win64 + AvailablePlatforms=Win64;Android EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6EE39883-7339-3FB6-AD82-931FB137D37F}.DebugGame Editor|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64 - {6EE39883-7339-3FB6-AD82-931FB137D37F}.DebugGame|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64 - {6EE39883-7339-3FB6-AD82-931FB137D37F}.Development Editor|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64 - {6EE39883-7339-3FB6-AD82-931FB137D37F}.Development|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64 - {6EE39883-7339-3FB6-AD82-931FB137D37F}.Shipping|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64 - {AF5A253A-0F37-38CE-8998-45CA936C112B}.DebugGame Editor|Win64.ActiveCfg = DebugGame_Editor|x64 - {AF5A253A-0F37-38CE-8998-45CA936C112B}.DebugGame Editor|Win64.Build.0 = DebugGame_Editor|x64 - {AF5A253A-0F37-38CE-8998-45CA936C112B}.DebugGame|Win64.ActiveCfg = DebugGame|x64 - {AF5A253A-0F37-38CE-8998-45CA936C112B}.DebugGame|Win64.Build.0 = DebugGame|x64 - {AF5A253A-0F37-38CE-8998-45CA936C112B}.Development Editor|Win64.ActiveCfg = Development_Editor|x64 - {AF5A253A-0F37-38CE-8998-45CA936C112B}.Development Editor|Win64.Build.0 = Development_Editor|x64 - {AF5A253A-0F37-38CE-8998-45CA936C112B}.Development|Win64.ActiveCfg = Development|x64 - {AF5A253A-0F37-38CE-8998-45CA936C112B}.Development|Win64.Build.0 = Development|x64 - {AF5A253A-0F37-38CE-8998-45CA936C112B}.Shipping|Win64.ActiveCfg = Shipping|x64 - {AF5A253A-0F37-38CE-8998-45CA936C112B}.Shipping|Win64.Build.0 = Shipping|x64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.DebugGame Editor|Android.ActiveCfg = Invalid|x64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.DebugGame Editor|Win64.ActiveCfg = DebugGame_Editor|x64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.DebugGame Editor|Win64.Build.0 = DebugGame_Editor|x64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.DebugGame|Android.ActiveCfg = Android_DebugGame|Win64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.DebugGame|Android.Build.0 = Android_DebugGame|Win64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.DebugGame|Win64.ActiveCfg = DebugGame|x64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.DebugGame|Win64.Build.0 = DebugGame|x64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Development Editor|Android.ActiveCfg = Invalid|x64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Development Editor|Win64.ActiveCfg = Development_Editor|x64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Development Editor|Win64.Build.0 = Development_Editor|x64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Development|Android.ActiveCfg = Android_Development|Win64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Development|Android.Build.0 = Android_Development|Win64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Development|Win64.ActiveCfg = Development|x64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Development|Win64.Build.0 = Development|x64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Shipping|Android.ActiveCfg = Android_Shipping|Win64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Shipping|Android.Build.0 = Android_Shipping|Win64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Shipping|Win64.ActiveCfg = Shipping|x64 + {B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Shipping|Win64.Build.0 = Shipping|x64 + {C48D0E9D-C862-3EA3-96A7-752EE9D06362}.DebugGame Editor|Android.ActiveCfg = BuiltWithUnrealBuildTool|Win64 + {C48D0E9D-C862-3EA3-96A7-752EE9D06362}.DebugGame Editor|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64 + {C48D0E9D-C862-3EA3-96A7-752EE9D06362}.DebugGame|Android.ActiveCfg = BuiltWithUnrealBuildTool|Win64 + {C48D0E9D-C862-3EA3-96A7-752EE9D06362}.DebugGame|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64 + {C48D0E9D-C862-3EA3-96A7-752EE9D06362}.Development Editor|Android.ActiveCfg = BuiltWithUnrealBuildTool|Win64 + {C48D0E9D-C862-3EA3-96A7-752EE9D06362}.Development Editor|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64 + {C48D0E9D-C862-3EA3-96A7-752EE9D06362}.Development|Android.ActiveCfg = BuiltWithUnrealBuildTool|Win64 + {C48D0E9D-C862-3EA3-96A7-752EE9D06362}.Development|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64 + {C48D0E9D-C862-3EA3-96A7-752EE9D06362}.Shipping|Android.ActiveCfg = BuiltWithUnrealBuildTool|Win64 + {C48D0E9D-C862-3EA3-96A7-752EE9D06362}.Shipping|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {6EE39883-7339-3FB6-AD82-931FB137D37F} = {233774A8-CC9D-3FA9-86D1-90573E92B704} - {AF5A253A-0F37-38CE-8998-45CA936C112B} = {DE1F8B53-6C02-3C13-9101-A7C8D96F3FF6} + {C48D0E9D-C862-3EA3-96A7-752EE9D06362} = {233774A8-CC9D-3FA9-86D1-90573E92B704} + {B95E7D0E-DB45-3765-9058-E00EBBC4B157} = {DE1F8B53-6C02-3C13-9101-A7C8D96F3FF6} EndGlobalSection EndGlobal diff --git a/Resources/Music.png b/Resources/Music.png new file mode 100644 index 0000000..8c591da Binary files /dev/null and b/Resources/Music.png differ diff --git a/Source/Cut5/Interface/SoundInterface.cpp b/Source/Cut5/Interface/SoundInterface.cpp index 8fff424..a442645 100644 --- a/Source/Cut5/Interface/SoundInterface.cpp +++ b/Source/Cut5/Interface/SoundInterface.cpp @@ -8,6 +8,7 @@ FCriticalSection Mutex; FSoundThread::FSoundThread(int32 OutputChannel, int32 SampleRate) : FRunnable() { + Stream = nullptr; Pa_Initialize(); Pa_OpenDefaultStream(&Stream, 0, OutputChannel, paFloat32, SampleRate, 0, nullptr, nullptr); Pa_StartStream(Stream); @@ -23,7 +24,12 @@ bool FSoundThread::Init() void FSoundThread::Exit() { - Pa_Terminate(); + if (Stream != nullptr && Pa_IsStreamActive(Stream)) + { + Pa_StopStream(Stream); + // Pa_Terminate(); + } + FRunnable::Exit(); } @@ -37,7 +43,10 @@ uint32 FSoundThread::Run() const int32 FrameLength = Audio.Num(); for (int32 i = SeekedFrame * (SampleRate / 26) * 4 * 2; i < (SeekedFrame + 1) * (SampleRate / 26) * 4 * 2 && i < FrameLength; ++i) { - ResultData.Add(Audio[i]); + if (ResultData.Num() < i && i > 0) + { + ResultData.Add(Audio[i]); + } } Pa_WriteStream(Stream, ResultData.GetData(), ResultData.Num() / 4 / 2); SeekedFrame = 0; diff --git a/Source/Cut5/MainHUD.cpp b/Source/Cut5/MainHUD.cpp index 9e1da34..d87f547 100644 --- a/Source/Cut5/MainHUD.cpp +++ b/Source/Cut5/MainHUD.cpp @@ -23,7 +23,7 @@ AMainHUD::AMainHUD() ); GEngine->bUseFixedFrameRate = 1; - GEngine->FixedFrameRate = 60000.0f; + GEngine->FixedFrameRate = 120.0f; UWidgetBlueprintLibrary::SetInputMode_UIOnlyEx(UGameplayStatics::GetPlayerController(GWorld, 0), nullptr, EMouseLockMode::DoNotLock); diff --git a/Source/Cut5/Utils/FFMPEGUtils.cpp b/Source/Cut5/Utils/FFMPEGUtils.cpp index 81ab348..82d9f90 100644 --- a/Source/Cut5/Utils/FFMPEGUtils.cpp +++ b/Source/Cut5/Utils/FFMPEGUtils.cpp @@ -269,6 +269,10 @@ TArray FFFMPEGUtils::GetMovieBrush(FClipData* ClipData, bool Regene if (ClipData->ResourcePropertyDataPtr) { + if (ClipData->ResourcePropertyDataPtr->VideoCodecContext == nullptr) + { + return {}; + } const float ClipLength = (ClipData->VideoEndFrame - ClipData->VideoStartFrame) * FGlobalData::DefaultTimeTickSpace; const float FrameNum = ClipLength / 128.0; const float TotalFrame = ClipData->ResourcePropertyDataPtr->VideoCodecContext->framerate.num * ( ClipData->ResourcePropertyDataPtr->Context->duration / AV_TIME_BASE); @@ -329,11 +333,9 @@ TArray FFFMPEGUtils::GetMovieBrush(FClipData* ClipData, bool Regene FGuid Guid = FGuid::NewGuid(); ExportImage(Texture, *FPaths::Combine(FUtils::GetTempPath() / ClipData->ClipGuid.ToString() / Guid.ToString() + ".png")); ClipData->MovieBrushesPath.Add(FPaths::Combine(FUtils::GetTempPath() / ClipData->ClipGuid.ToString() / Guid.ToString() + ".png")); - + FSlateDynamicImageBrush Brush = FSlateDynamicImageBrush(*ClipData->MovieBrushesPath[i], FVector2f(0, 0)); + Result.Add(Brush); - FSlateBrush NewBrush; - NewBrush.SetResourceObject(Texture); - Result.Add(NewBrush); delete RawData; } @@ -351,6 +353,25 @@ TArray FFFMPEGUtils::GetAudioBrush(FClipData* ClipData) const int32 PicLength = TimeLength / 8.0; + if (ClipData->ResourcePropertyDataPtr) + { + if (ClipData->ResourcePropertyDataPtr->AudioData.Num() == 0) + { + return {}; + } + if (ClipData->ResourcePropertyDataPtr->AudioStream == -1) + { + return {}; + } + if (ClipData->ResourcePropertyDataPtr->VideoStream != -1) + { + return {}; + } + } + else + { + return {}; + } int32 DownSampleSpace = 128; TArray DownSampledData; diff --git a/Source/Cut5/Utils/Utils.cpp b/Source/Cut5/Utils/Utils.cpp index fef5d24..159eb71 100644 --- a/Source/Cut5/Utils/Utils.cpp +++ b/Source/Cut5/Utils/Utils.cpp @@ -139,7 +139,7 @@ void FUtils::CreateDefaultTimelineSave(const FString& SavedPath, const FTimeline MemoryWriter << ClipLength; MemoryWriter << AllClips; FFileHelper::SaveArrayToFile(SavedData, *SavedPath); - + // GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("CreateDefaultTimelineSave %s"), *SavedPath)); // FFileHelper::LoadFileToArray(SavedData, *FPaths::Combine(FPaths::ProjectSavedDir(), Type == FTimelineInfo::ETimelineType::Main ? TEXT("Default.sav") : TEXT("DefaultFX.sav"))); } diff --git a/Source/Cut5/Widgets/Commands/ShortcunCommands.h b/Source/Cut5/Widgets/Commands/ShortcunCommands.h index 14e96e0..8a35fe0 100644 --- a/Source/Cut5/Widgets/Commands/ShortcunCommands.h +++ b/Source/Cut5/Widgets/Commands/ShortcunCommands.h @@ -14,13 +14,14 @@ public: TSharedPtr CutMode; TSharedPtr SelectMode; TSharedPtr AutoMagnet; - - TSharedPtr LeftPerFrame; TSharedPtr RightPerFrame; TSharedPtr PlayFrame; TSharedPtr Delete; + TSharedPtr TimelineMoveLeft; + TSharedPtr TimelineMoveRight; + }; diff --git a/Source/Cut5/Widgets/Commands/ShortcutCommands.cpp b/Source/Cut5/Widgets/Commands/ShortcutCommands.cpp index b7f0b6a..7c14387 100644 --- a/Source/Cut5/Widgets/Commands/ShortcutCommands.cpp +++ b/Source/Cut5/Widgets/Commands/ShortcutCommands.cpp @@ -3,15 +3,17 @@ #define LOCTEXT_NAMESPACE "FShortCutCommands" void FShortCutCommands::RegisterCommands() { - UI_COMMAND(CutMode, "剪刀模式", "Executes My FCurtainCommands", EUserInterfaceActionType::Button, FInputChord(EKeys::B)); - UI_COMMAND(SelectMode, "选择模式", "Executes My FCurtainCommands", EUserInterfaceActionType::Button, FInputChord(EKeys::A)); - UI_COMMAND(ZoomInTimeline, "放大时间线", "Executes My FCurtainCommands", EUserInterfaceActionType::Button, FInputChord(EKeys::Equals, EModifierKey::Alt)); - UI_COMMAND(ZoomOutTimeline, "缩小时间线", "Executes My FCurtainCommands", EUserInterfaceActionType::Button, FInputChord(EKeys::Hyphen, EModifierKey::Alt)); - UI_COMMAND(ExportXML, "导出XML", "Executes My FCurtainCommands", EUserInterfaceActionType::Button, FInputChord(EKeys::E, EModifierKey::Alt)); - UI_COMMAND(PlayFrame, "播放", "Executes My FCurtainCommands", EUserInterfaceActionType::Button, FInputChord(EKeys::SpaceBar)); - UI_COMMAND(LeftPerFrame, "左移一帧", "Executes My FCurtainCommands", EUserInterfaceActionType::Button, FInputChord(EKeys::LeftBracket)); - UI_COMMAND(Delete, "删除", "Executes My FCurtainCommands", EUserInterfaceActionType::Button, FInputChord(EKeys::Delete)); - UI_COMMAND(RightPerFrame, "右移一帧", "Executes My FCurtainCommands", EUserInterfaceActionType::Button, FInputChord(EKeys::RightBracket)); + UI_COMMAND(CutMode, "剪刀模式", "Executes My FCurtainCommands", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::B)); + UI_COMMAND(SelectMode, "选择模式", "Executes My FCurtainCommands", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::A)); + UI_COMMAND(ZoomInTimeline, "放大时间线", "Executes My FCurtainCommands", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::Equals, EModifierKey::Alt)); + UI_COMMAND(ZoomOutTimeline, "缩小时间线", "Executes My FCurtainCommands", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::Hyphen, EModifierKey::Alt)); + UI_COMMAND(ExportXML, "导出XML", "Executes My FCurtainCommands", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::E, EModifierKey::Alt)); + UI_COMMAND(PlayFrame, "播放", "Executes My FCurtainCommands", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::SpaceBar)); + UI_COMMAND(LeftPerFrame, "左移一帧", "Executes My FCurtainCommands", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::LeftBracket)); + UI_COMMAND(Delete, "删除", "Executes My FCurtainCommands", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::Delete)); + UI_COMMAND(RightPerFrame, "右移一帧", "Executes My FCurtainCommands", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::RightBracket)); + UI_COMMAND(TimelineMoveLeft, "左侧移动时间轴", "Executes My FCurtainCommands", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::MouseScrollDown, EModifierKey::Shift)); + UI_COMMAND(TimelineMoveRight, "右侧移动时间轴", "Executes My FCurtainCommands", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::MouseScrollUp, EModifierKey::Shift)); } #undef LOCTEXT_NAMESPACE diff --git a/Source/Cut5/Widgets/Curtain/SCurtain.cpp b/Source/Cut5/Widgets/Curtain/SCurtain.cpp index 919d0ba..4087cec 100644 --- a/Source/Cut5/Widgets/Curtain/SCurtain.cpp +++ b/Source/Cut5/Widgets/Curtain/SCurtain.cpp @@ -46,32 +46,7 @@ void SCurtain::Construct(const FArguments& InArgs) .ButtonStyle(FCutButtonStyle::Get(), Curtain->bIsActive ? "Curtain.CurtainButtonSelected" : "Curtain.CurtainButton") .OnClicked_Lambda([this]() { - CurtainPanel->DeSelectedAll(); - Curtain->bIsActive = true; - CurtainPanel->CallRender(); - - - // 没有Curtain就Create一个 - if (!FPaths::FileExists(FUtils::CurtainFullPath(Curtain->CurtainUUID.ToString()))) - { - FUtils::CreateDefaultTimelineSave(FUtils::CurtainFullPath(Curtain->CurtainUUID.ToString()), FTimelineInfo::ETimelineType::FX); - { - FSaveModifier SaveModifier(FUtils::CurtainFullPath(Curtain->CurtainUUID.ToString())); - SaveModifier.TimelineInfo.CurrentOpenFullPath = FUtils::CurtainFullPath(Curtain->CurtainUUID.ToString()); - SaveModifier.TimelineInfo.CurrentOpenType = FTimelineInfo::ETimelineType::FX; - Curtain->TimelineInfo = SaveModifier.TimelineInfo; - } - } - CurtainPanel->MainWidgetInterface->OpenTimeline(FUtils::CurtainFullPath(Curtain->CurtainUUID.ToString()), true); - - - - - TSharedPtr CurtainDragDrop = MakeShared(); - CurtainDragDrop->CurtainIndex = CurtainIndex; - CurtainDragDrop->GroupIndex = CurtainGroup - &CurtainPanel->Groups[0]; - CurtainDragDrop->DragDropType = FCutDragDropBase::EType::CurtainDrag; - CurtainDragDrop->DraggingWidget = SharedThis(this); + TSharedPtr CurtainDragDrop = OpenThis(); return FReply::Handled().DetectDrag(SharedThis(this), EKeys::LeftMouseButton).BeginDragDrop(CurtainDragDrop.ToSharedRef()); }) ] @@ -101,6 +76,11 @@ void SCurtain::Construct(const FArguments& InArgs) ] ] ]; + + if (Curtain->bIsActive) + { + FSlateApplication::Get().SetKeyboardFocus(InlineEditableTextBlock); + } } FReply SCurtain::OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) @@ -132,8 +112,45 @@ FReply SCurtain::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEv CurtainPanel->ShowCurtainCommand(Curtain->CurtainUUID); return FReply::Handled(); } + if (!Curtain->bIsActive) + { + OpenThis(); + } return SCompoundWidget::OnMouseButtonDown(MyGeometry, MouseEvent); } + +TSharedPtr SCurtain::OpenThis() +{ + CurtainPanel->DeSelectedAll(); + Curtain->bIsActive = true; + CurtainPanel->CallRender(); + + + // 没有Curtain就Create一个 + if (!FPaths::FileExists(FUtils::CurtainFullPath(Curtain->CurtainUUID.ToString()))) + { + FUtils::CreateDefaultTimelineSave(FUtils::CurtainFullPath(Curtain->CurtainUUID.ToString()), FTimelineInfo::ETimelineType::FX); + { + FSaveModifier SaveModifier(FUtils::CurtainFullPath(Curtain->CurtainUUID.ToString())); + SaveModifier.TimelineInfo.CurrentOpenFullPath = FUtils::CurtainFullPath(Curtain->CurtainUUID.ToString()); + SaveModifier.TimelineInfo.CurrentOpenType = FTimelineInfo::ETimelineType::FX; + Curtain->TimelineInfo = SaveModifier.TimelineInfo; + } + } + CurtainPanel->MainWidgetInterface->OpenTimeline(FUtils::CurtainFullPath(Curtain->CurtainUUID.ToString()), true); + + + + + TSharedPtr CurtainDragDrop = MakeShared(); + CurtainDragDrop->CurtainIndex = CurtainIndex; + CurtainDragDrop->GroupIndex = CurtainGroup - &CurtainPanel->Groups[0]; + CurtainDragDrop->DragDropType = FCutDragDropBase::EType::CurtainDrag; + CurtainDragDrop->DraggingWidget = SharedThis(this); + + return CurtainDragDrop; +} + END_SLATE_FUNCTION_BUILD_OPTIMIZATION diff --git a/Source/Cut5/Widgets/Curtain/SCurtain.h b/Source/Cut5/Widgets/Curtain/SCurtain.h index b386c08..b547643 100644 --- a/Source/Cut5/Widgets/Curtain/SCurtain.h +++ b/Source/Cut5/Widgets/Curtain/SCurtain.h @@ -32,7 +32,10 @@ public: int32 CurtainIndex; TSharedPtr InlineEditableTextBlock; TSharedPtr CurtainButton; + TSharedPtr OpenThis(); // FButtonStyle UnSelectedButtonStyle; FButtonStyle SelectedButtonStyle = FButtonStyle::GetDefault(); }; + + diff --git a/Source/Cut5/Widgets/Curtain/SCurtainPanel.cpp b/Source/Cut5/Widgets/Curtain/SCurtainPanel.cpp index 19dccfd..74500a9 100644 --- a/Source/Cut5/Widgets/Curtain/SCurtainPanel.cpp +++ b/Source/Cut5/Widgets/Curtain/SCurtainPanel.cpp @@ -127,7 +127,7 @@ void SCurtainPanel::Construct(const FArguments& InArgs) .Padding(10.0) [ SAssignNew(Title, STextBlock) - .Text(FText::FromString(FGlobalData::CurrentProjectName)) + .Text_Lambda([](){ return FText::FromString(FGlobalData::CurrentProjectName); }) .Justification(ETextJustify::Left) ] + SVerticalBox::Slot() diff --git a/Source/Cut5/Widgets/DefineGlobal.h b/Source/Cut5/Widgets/DefineGlobal.h index 83a7339..bc4cbd3 100644 --- a/Source/Cut5/Widgets/DefineGlobal.h +++ b/Source/Cut5/Widgets/DefineGlobal.h @@ -4,6 +4,7 @@ #include "Cut5/WidgetInterface.h" + #include "Widgets/Input/SEditableTextBox.h" extern "C"{ @@ -508,6 +509,7 @@ public: DragDropType = InType; } TSharedPtr DraggingWidget; + TSharedPtr VirtualDraggingShow; TSharedPtr OverrideWidget; TSharedPtr MoveAboutWidget; class ICutMainWidgetInterface* MainInterface; @@ -515,7 +517,11 @@ public: float OriginOffset = 0.0f; EType DragDropType = EType::TrackClip; ETrackType ManualClipType = ETrackType::None; - + + virtual TSharedPtr GetDefaultDecorator() const override + { + return DraggingWidget.ToSharedRef(); + }; }; class CUT5_API FTrackClipDragOperation final : public FCutDragDropBase diff --git a/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp b/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp index 0810073..1fff968 100644 --- a/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp +++ b/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp @@ -105,14 +105,53 @@ void DragDropOperator::UpdateClipProcess(ICutMainWidgetInterface* MainInterface, return; } - - +void DragDropOperator::CloseCursorDecorator() +{ + if (CurrentShowDragDropWindow) + { + CurrentShowDragDropWindow->DestroyWindowImmediately(); + CurrentShowDragDropWindow.Reset(); + } +} void DragDropOperator::OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) { + if (TSharedPtr DragDropBase = DragDropEvent.GetOperationAs()) + { + return; + } if (TSharedPtr DragDropBase = DragDropEvent.GetOperationAs()) { + // if (DragDropBase->VirtualDraggingShow && DragDropBase->MainInterface) + // { + // if (!CurrentShowDragDropWindow) + // { + // CurrentShowDragDropWindow = SWindow::MakeCursorDecorator(); + // CurrentShowDragDropWindow->SetContent(DragDropBase->VirtualDraggingShow.ToSharedRef()); + // FSlateApplication::Get().AddWindowAsNativeChild(CurrentShowDragDropWindow.ToSharedRef(), FSlateApplication::Get().GetActiveTopLevelWindow().ToSharedRef(), true); + // } + // CurrentShowDragDropWindow->MoveWindowTo(FSlateApplication::Get().GetCursorPos()); + // // CurrentShowDragDropWidget = DragDropBase->VirtualDraggingShow.ToSharedRef(); + // // SCutMainWindow* MainWindow = static_cast(SavedMainInterface); + // // if (MainWindow) + // // { + // // MainWindow->Overlay->AddSlot() + // // .HAlign(HAlign_Left) + // // .VAlign(VAlign_Top) + // // [ + // // SNew(SBox) + // // .WidthOverride(80) + // // .HeightOverride(80) + // // .HAlign(HAlign_Fill) + // // .VAlign(VAlign_Fill) + // // [ + // // CurrentShowDragDropWidget.ToSharedRef() + // // ] + // // ]; + // // } + // + // } TSharedPtr ClipsMoveDragDropBase = StaticCastSharedPtr(DragDropBase); if (DragDropBase->DragDropType == FCutDragDropBase::EType::ClipsMove) { @@ -251,7 +290,16 @@ void DragDropOperator::OnDragOver(const FGeometry& MyGeometry, const FDragDropEv return; } TickTimeline->UpdateNewCursorPosition((TickTimeline->GetCachedGeometry().AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X) / FGlobalData::DefaultTimeTickSpace); - + if (TickTimeline->CutTimeline->AutoPlaying == false) + { + int32 NewFrame = (TickTimeline->GetCachedGeometry().AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X) / FGlobalData::DefaultTimeTickSpace; + for (FSingleTrackGroupInstance& Instance : TickTimeline->CutTimeline->TrackGroupInstances) + { + Instance.Body->Seek(NewFrame); + } + TickTimeline->CutTimeline->CurrentTimeData->SetText(FText::FromString(FGlobalData::GetTimeData(NewFrame) + " / ")); + } + return; } @@ -368,6 +416,12 @@ void DragDropOperator::OnDragOver(const FGeometry& MyGeometry, const FDragDropEv const auto& DragDropOperation = static_cast(DragDropEvent.GetOperation().ToSharedRef().Get()); TSharedPtr Body = StaticCastSharedPtr(DragDropOperation.OverrideWidget); + + if (DragDropOperation.DragDropType == FCutDragDropBase::EType::Device) + { + + } + if (DragDropOperation.DragDropType == FCutDragDropBase::EType::Clip2Clip) { const int32 NewPos = (Body->MainWidgetInterface->GetCutTimeline()->GetCachedGeometry().AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X - DragDropOperation.DragOffset) / FGlobalData::DefaultTimeTickSpace; @@ -421,7 +475,7 @@ void DragDropOperator::OnDragOver(const FGeometry& MyGeometry, const FDragDropEv if (TimelineClip == Clip) continue;; - GEngine->AddOnScreenDebugMessage(-1, 0.1f, FColor::Red, FString::Printf(TEXT("ClipStartFrame:%d, LoopClipFrame:%d"), TimelineClip->ClipData->ClipStartFrame + NewPos, Clip->ClipData->ClipStartFrame)); + // GEngine->AddOnScreenDebugMessage(-1, 0.1f, FColor::Red, FString::Printf(TEXT("ClipStartFrame:%d, LoopClipFrame:%d"), TimelineClip->ClipData->ClipStartFrame + NewPos, Clip->ClipData->ClipStartFrame)); if ((TimelineClip->ClipData->ClipStartFrame + NewPos) == Clip->ClipData->ClipEndFrame) { @@ -450,10 +504,13 @@ void DragDropOperator::OnDragOver(const FGeometry& MyGeometry, const FDragDropEv { } + return; } void DragDropOperator::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent, TSharedPtr DropWidget) { + + const auto& DragDropOperation = static_cast(DragDropEvent.GetOperation().ToSharedRef().Get()); if (DragDropOperation.DragDropType == FCutDragDropBase::EType::ClipsMove) diff --git a/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.h b/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.h index dfd3873..31a0225 100644 --- a/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.h +++ b/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.h @@ -13,6 +13,10 @@ public: 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); + void CloseCursorDecorator(); + ICutMainWidgetInterface* SavedMainInterface; + TSharedPtr CurrentShowDragDropWidget; + TSharedPtr CurrentShowDragDropWindow; }; diff --git a/Source/Cut5/Widgets/FX/SEffectCard.cpp b/Source/Cut5/Widgets/FX/SEffectCard.cpp index d914eb3..5a98b59 100644 --- a/Source/Cut5/Widgets/FX/SEffectCard.cpp +++ b/Source/Cut5/Widgets/FX/SEffectCard.cpp @@ -58,7 +58,7 @@ void SEffectCard::Construct(const FArguments& InArgs) .OnClicked_Lambda([this]() { - MainInterface->OpenTimeline(FUtils::SingleCardFullPath(CardProperty->Name), true); + MainInterface->OpenTimeline(FUtils::SingleCardFullPath(CardProperty->Guid.ToString()), true); PropertiesInterfaceGUID = CardProperty->Guid; MainInterface->CurrentSelectedPropertiesInterfaceGuid = CardProperty->Guid; MainInterface->UpdateProperties(this); diff --git a/Source/Cut5/Widgets/FX/SEffectCardGroup.cpp b/Source/Cut5/Widgets/FX/SEffectCardGroup.cpp index 20090a2..cb63881 100644 --- a/Source/Cut5/Widgets/FX/SEffectCardGroup.cpp +++ b/Source/Cut5/Widgets/FX/SEffectCardGroup.cpp @@ -15,6 +15,7 @@ #include "Widgets/Layout/SScrollBox.h" #include "Widgets/Text/SInlineEditableTextBlock.h" #include "Cut5/Widgets/FX/SEffectCardsPanel.h" +#include "Cut5/Widgets/MicroWidgets/STips.h" BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION @@ -414,7 +415,7 @@ void SEffectCardGroup::CallRender() .WidthOverride(76) .HeightOverride(76) [ - SNew(SOverlay) + SAssignNew(Overlay, SOverlay) + SOverlay::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) @@ -428,6 +429,17 @@ void SEffectCardGroup::CallRender() FEffectCardProperty NewCard; NewCard.Name = TEXT("未命名") + NewCard.Guid.ToString(); + int32 ID = 0; + for (int32 i = 0; i < EffectCardPanel->EffectCardGroups.Num(); i++) + { + for (int32 j = 0; j < EffectCardPanel->EffectCardGroups[i].Cards.Num(); j++) + { + ID++; + } + ID++; + } + NewCard.ID = ID; + FUtils::CreateDefaultTimelineSave(FUtils::SingleCardFullPath(NewCard.Guid.ToString()), FTimelineInfo::ETimelineType::FX); { FSaveModifier SaveModifier(FUtils::SingleCardFullPath(NewCard.Guid.ToString())); @@ -486,6 +498,56 @@ TSharedPtr SEffectCardGroup::GetPropertiesWidget() return PropertiesWidget; } + +void SEffectCardGroup::ShowClosedButton(bool bShow) +{ + if (bShow) + { + ClosedButton = SNew(SButton) + .ButtonStyle(FCoreStyle::Get(), "NoBorder") + .Content() + [ + SNew(SImage) + .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("close-circle-fill.png"), {16, 16})) + ] + .OnClicked_Lambda([this]() + { + GEngine->GameViewport->AddViewportWidgetContent( + SNew(STips) + .Title(TEXT("确定删除特效卡吗?")) + .SubTitle(TEXT("特效卡删除后不可恢复")) + .OnEnsure_Lambda([this](const FString& String) + { + if (EffectCardGroup->bIsActive) + { + MainInterface->OnSelectCard(EffectCardGroup->Guid); + } + EffectCardPanel->RemoveCard(EffectCardGroup->Guid); + }), 1 + ); + + + return FReply::Handled(); + }); + Overlay->AddSlot() + .VAlign(VAlign_Top) + .HAlign(HAlign_Right) + [ + ClosedButton.ToSharedRef() + ]; + } + else + { + if (ClosedButton) + { + Overlay->RemoveSlot(ClosedButton.ToSharedRef()); + ClosedButton.Reset(); + } + + } + +} + FReply SEffectCardGroup::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) { TSharedPtr EffectCardDragDrop = DragDropEvent.GetOperationAs(); @@ -500,4 +562,16 @@ FReply SEffectCardGroup::OnDrop(const FGeometry& MyGeometry, const FDragDropEven return SCompoundWidget::OnDrop(MyGeometry, DragDropEvent); } +void SEffectCardGroup::OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) +{ + ShowClosedButton(true); + +} + +void SEffectCardGroup::OnMouseLeave(const FPointerEvent& MouseEvent) +{ + ShowClosedButton(false); + +} + END_SLATE_FUNCTION_BUILD_OPTIMIZATION diff --git a/Source/Cut5/Widgets/FX/SEffectCardGroup.h b/Source/Cut5/Widgets/FX/SEffectCardGroup.h index 51f7b4d..f1b3712 100644 --- a/Source/Cut5/Widgets/FX/SEffectCardGroup.h +++ b/Source/Cut5/Widgets/FX/SEffectCardGroup.h @@ -56,6 +56,9 @@ public: virtual TSharedPtr GetPropertiesWidget() override; + void ShowClosedButton(bool bShow); + TSharedPtr ClosedButton; + TSharedPtr Overlay; TSharedPtr PropertiesWidget; @@ -65,4 +68,7 @@ public: TSharedPtr>> GroupComboBox; TSharedPtr>> JumpStepComboBox; + virtual void OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; + virtual void OnMouseLeave(const FPointerEvent& MouseEvent) override; + }; diff --git a/Source/Cut5/Widgets/FX/SEffectCardsPanel.cpp b/Source/Cut5/Widgets/FX/SEffectCardsPanel.cpp index d25af07..153e9ad 100644 --- a/Source/Cut5/Widgets/FX/SEffectCardsPanel.cpp +++ b/Source/Cut5/Widgets/FX/SEffectCardsPanel.cpp @@ -104,7 +104,16 @@ void SEffectCardsPanel::CallRender() .OnClicked_Lambda([this]() { FEffectCardGroup* Group = AddNewGroup(TEXT("新建组") + FGuid::NewGuid().ToString()); - + int32 ID = 0; + for (int32 i = 0; i < EffectCardGroups.Num(); i++) + { + for (int32 j = 0; j < EffectCardGroups[i].Cards.Num(); j++) + { + ID++; + } + ID++; + } + Group->ID = ID; const FString NewPath = FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName, TEXT("FX"), FGuid::NewGuid().ToString() + TEXT(".bin")); FUtils::CreateDefaultTimelineSave(NewPath, FTimelineInfo::ETimelineType::FX); { @@ -144,8 +153,19 @@ void SEffectCardsPanel::AddNewCard(FEffectCardProperty CardProperty, const FStri void SEffectCardsPanel::RemoveCard(const FGuid& GUID) { // Search in all group to find GUID equal to the GUID. + int32 j = 0; for (FEffectCardGroup& Group : EffectCardGroups) { + if (!Group.bIsDedicated && Group.Guid == GUID) + { + if (Group.bIsActive == true) + { + MainInterface->OpenTimeline(FUtils::MainSaveFullPath()); + } + EffectCardGroups.RemoveAt(j); + break; + } + int32 i = 0; for (FEffectCardProperty& Property : Group.Cards) { @@ -160,6 +180,7 @@ void SEffectCardsPanel::RemoveCard(const FGuid& GUID) } i++; } + j++; } CallRender(); } diff --git a/Source/Cut5/Widgets/MicroWidgets/SColorPanel.cpp b/Source/Cut5/Widgets/MicroWidgets/SColorPanel.cpp index 9dd7702..2547972 100644 --- a/Source/Cut5/Widgets/MicroWidgets/SColorPanel.cpp +++ b/Source/Cut5/Widgets/MicroWidgets/SColorPanel.cpp @@ -136,17 +136,17 @@ void SColorPanel::Construct(const FArguments& InArgs) + SOverlay::Slot() .HAlign(HAlign_Right) .VAlign(VAlign_Top) + .Padding(0, 0, 16, 16) [ SNew(SBox) .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) - .Padding(0, 0, 16, 16) + .Padding(0, 0, 0, 0) .WidthOverride(24) .HeightOverride(24) [ SNew(SImage) - .DesiredSizeOverride(FVector2D(24, 24)) - .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("ColorPanelClose.png"), {24, 24})) + .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("ColorPanelClose.png"), {})) .OnMouseButtonDown_Lambda([this](const FGeometry&, const FPointerEvent&) { GEngine->GameViewport->RemoveViewportWidgetContent(SharedThis(this)); @@ -163,6 +163,7 @@ void SColorPanel::Construct(const FArguments& InArgs) .HeightOverride(12) [ SAssignNew(ColorBarHCircle, SImage) + .Visibility(EVisibility::HitTestInvisible) .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("ColorSelectCircle.png"), {16, 16})) ] @@ -176,6 +177,7 @@ void SColorPanel::Construct(const FArguments& InArgs) .HeightOverride(12) [ SAssignNew(ColorBarVCircle, SImage) + .Visibility(EVisibility::HitTestInvisible) .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("ColorSelectCircle.png"), {16, 16})) ] ] @@ -188,6 +190,7 @@ void SColorPanel::Construct(const FArguments& InArgs) .HeightOverride(12) [ SAssignNew(ColorBarSCircle, SImage) + .Visibility(EVisibility::HitTestInvisible) .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("ColorSelectCircle.png"), {16, 16})) ] ] @@ -220,9 +223,9 @@ FReply SColorPanel::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent void SColorPanel::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) { - ColorBarHCircle->SetRenderTransform(FVector2D(18 + (CurrentSelectColor.R / 360.0f * 286), 242)); - ColorBarSCircle->SetRenderTransform(FVector2D(18 + (ColorS * 286), ColorSHeight + 56)); - ColorBarVCircle->SetRenderTransform(FVector2D(18 + (CurrentSelectColor.B * 286), 268)); + ColorBarHCircle->SetRenderTransform(FVector2D(12 + (CurrentSelectColor.R / 360.0f * 288), 242)); + ColorBarSCircle->SetRenderTransform(FVector2D(12 + (ColorS * 286), ColorSHeight + 56 - 6)); + ColorBarVCircle->SetRenderTransform(FVector2D(12 + (CurrentSelectColor.B * 288), 268)); ColorImage->SetColorAndOpacity(GetColor()); *ColorPtr = GetColor(); diff --git a/Source/Cut5/Widgets/MicroWidgets/SNewProjectTips.cpp b/Source/Cut5/Widgets/MicroWidgets/SNewProjectTips.cpp index 36aa5db..831902a 100644 --- a/Source/Cut5/Widgets/MicroWidgets/SNewProjectTips.cpp +++ b/Source/Cut5/Widgets/MicroWidgets/SNewProjectTips.cpp @@ -64,10 +64,14 @@ void SNewProjectTips::Construct(const FArguments& InArgs) .OnTextCommitted_Lambda([this](const FText& InText, ETextCommit::Type InCommitType) { - if (OnEnsure.ExecuteIfBound(InText.ToString())) + if (InCommitType == ETextCommit::Type::OnEnter) { + if (OnEnsure.ExecuteIfBound(InText.ToString())) + { + } } + }) diff --git a/Source/Cut5/Widgets/SCustomInputPanel.cpp b/Source/Cut5/Widgets/SCustomInputPanel.cpp index 6fecbe3..3cc6887 100644 --- a/Source/Cut5/Widgets/SCustomInputPanel.cpp +++ b/Source/Cut5/Widgets/SCustomInputPanel.cpp @@ -141,7 +141,7 @@ void SCustomInputPanel::Construct(const FArguments& InArgs) { bIsEditMode = false; ImportImage->SetImage(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("ImportVideo.png"), {})); - ImportText->SetText(FText::FromString(TEXT("导入视频"))); + ImportText->SetText(FText::FromString(TEXT("导入资产"))); for (int32 i = 0; i < ResourceInst.Num(); i++) { ResourceInst[i]->ShowCheckBox(false); @@ -250,78 +250,44 @@ void SCustomInputPanel::Construct(const FArguments& InArgs) } IDesktopPlatform* DesktopPlatformModule = FDesktopPlatformModule::Get(); TArray OpenFileName; - DesktopPlatformModule->OpenFileDialog(nullptr, (TEXT("打开文件")), TEXT(""), TEXT(""), TEXT(""), EFileDialogFlags::None, OpenFileName); - + DesktopPlatformModule->OpenFileDialog(nullptr, (TEXT("打开文件")), TEXT(""), TEXT(""), TEXT(""), EFileDialogFlags::Multiple, OpenFileName); for (int32 i = 0; i < OpenFileName.Num(); i++) { - if (FPaths::GetExtension(OpenFileName[i]) == "mp3") + FTimelinePropertyData Data; + if (FFFMPEGUtils::LoadMedia(OpenFileName[i], &Data) == TEXT("Failed")) { - FTimelinePropertyData Data; - FFFMPEGUtils::LoadMedia(OpenFileName[i], &Data); + continue; + }; - TSharedPtr Resource = SNew(SCustomInputResource) - .PropertyData(Data).OnCheckBoxChecked_Lambda([this](FTimelinePropertyData& Data, bool bIsChecked) - { - if (bIsChecked == true) - { - SelectedProperties.Add(Data); - } - else - { - SelectedProperties.Remove(Data); - } - - }); - GridPanel->AddSlot(GridPanel->GetChildren()->Num() % 2, GridPanel->GetChildren()->Num() / 2) - [ - Resource.ToSharedRef() - ]; - PropertyData.Add(Data); - ResourceInst.Add(Resource.ToSharedRef()); - if (bIsEditMode) - { - Resource->ShowCheckBox(true); - } - return FReply::Handled(); - } - else + TSharedPtr Resource = SNew(SCustomInputResource).MainInterface(MainWidgetInterface) + .PropertyData(Data).OnCheckBoxChecked_Lambda([this](FTimelinePropertyData& ClickedData, bool bIsChecked) { - FTimelinePropertyData Data; - if (FFFMPEGUtils::LoadMedia(OpenFileName[i], &Data) == TEXT("Failed")) + if (bIsChecked == true) { - return FReply::Handled(); - }; - - TSharedPtr Resource = SNew(SCustomInputResource) - .PropertyData(Data).OnCheckBoxChecked_Lambda([this](FTimelinePropertyData& ClickedData, bool bIsChecked) - { - if (bIsChecked == true) - { - SelectedProperties.Add(ClickedData); - } - else - { - for (int32 i = 0; i < SelectedProperties.Num(); i++) - { - if (SelectedProperties[i].Guid == ClickedData.Guid) - { - SelectedProperties.RemoveAt(i); - break; - } - } - - } - }); - GridPanel->AddSlot(GridPanel->GetChildren()->Num() % 2, GridPanel->GetChildren()->Num() / 2) - [ - Resource.ToSharedRef() - ]; - PropertyData.Add(Data); - ResourceInst.Add(Resource.ToSharedRef()); - if (bIsEditMode) - { - Resource->ShowCheckBox(true); + SelectedProperties.Add(ClickedData); } + else + { + for (int32 i = 0; i < SelectedProperties.Num(); i++) + { + if (SelectedProperties[i].Guid == ClickedData.Guid) + { + SelectedProperties.RemoveAt(i); + break; + } + } + + } + }); + GridPanel->AddSlot(GridPanel->GetChildren()->Num() % 2, GridPanel->GetChildren()->Num() / 2) + [ + Resource.ToSharedRef() + ]; + PropertyData.Add(Data); + ResourceInst.Add(Resource.ToSharedRef()); + if (bIsEditMode) + { + Resource->ShowCheckBox(true); } } @@ -339,7 +305,7 @@ void SCustomInputPanel::Construct(const FArguments& InArgs) .VAlign(VAlign_Center) [ SAssignNew(ImportText, STextBlock) - .Text(FText::FromString(TEXT("导入视频"))) + .Text(FText::FromString(TEXT("导入资产"))) .Justification(ETextJustify::Center) ] ] @@ -385,6 +351,25 @@ void SCustomInputPanel::Construct(const FArguments& InArgs) FReply SCustomInputPanel::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) { + if (TSharedPtr DragOperation = DragDropEvent.GetOperationAs()) + { + for (const FString& NewFile : DragOperation->GetFiles()) + { + FTimelinePropertyData Data; + if (FFFMPEGUtils::LoadMedia(NewFile, &Data) != TEXT("Failed")) + { + EffectGridPanel->AddSlot(EffectGridPanel->GetChildren()->Num() % 4, EffectGridPanel->GetChildren()->Num() / 4) + [ + SNew(SCustomInputResource) + .PropertyData(Data) + .MainInterface(MainWidgetInterface) + ]; + PropertyData.Add(Data); + } + + } + return FReply::Handled().EndDragDrop(); + } return FReply::Handled().EndDragDrop(); } @@ -551,6 +536,7 @@ void SCustomInputPanel::LoadPanel(const FString& LoadPlace) [ SNew(SCustomInputResource) .PropertyData(ReloadPropertyData) + .MainInterface(MainWidgetInterface) ]; PropertyData.Add(ReloadPropertyData); } diff --git a/Source/Cut5/Widgets/SCustomInputResource.cpp b/Source/Cut5/Widgets/SCustomInputResource.cpp index daa34f5..2c550fa 100644 --- a/Source/Cut5/Widgets/SCustomInputResource.cpp +++ b/Source/Cut5/Widgets/SCustomInputResource.cpp @@ -14,7 +14,7 @@ void SCustomInputResource::Construct(const FArguments& InArgs) PropertyData = InArgs._PropertyData; VideoCapture = InArgs._VideoCapture; OnCheckBoxChecked = InArgs._OnCheckBoxChecked; - CustomPresetName = InArgs._CustomPresetName; + MainInterface = InArgs._MainInterface; ChildSlot [ SNew(SBox) @@ -39,15 +39,17 @@ void SCustomInputResource::Construct(const FArguments& InArgs) .Padding(10.0) [ SNew(SImage) - .Image(PropertyData.bIsCustomPresetData == false ? FUtils::GetBrushFromImage(PropertyData.IconPath, {}) : FUtils::GetBrushFromImage(FUtils::GetResourcesPath("CustomPreset.png"), {})) + .Image( (PropertyData.VideoStream == -1 && PropertyData.AudioStream != -1) ? FUtils::GetBrushFromImage(FUtils::GetResourcesPath(TEXT("Music.png")), {}) : + PropertyData.bIsCustomPresetData == false ? FUtils::GetBrushFromImage(PropertyData.IconPath, {}) : FUtils::GetBrushFromImage(FUtils::GetResourcesPath("CustomPreset.png"), {})) ] + SOverlay::Slot() .HAlign(HAlign_Center) .VAlign(VAlign_Center) [ SNew(STextBlock) - .Text(FText::FromString(CustomPresetName)) - .Visibility(PropertyData.bIsCustomPresetData == true ? EVisibility::Visible : EVisibility::Collapsed) + .Text(FText::FromString(PropertyData.Name)) + .Font(FAppStyle::GetWidgetStyle("NormalText").Font) + // .Visibility(PropertyData.bIsCustomPresetData == true ? EVisibility::Visible : EVisibility::Collapsed) ] ] @@ -67,6 +69,17 @@ FReply SCustomInputResource::OnDragDetected(const FGeometry& MyGeometry, const F Operation->DraggingWidget = SharedThis(this); Operation->DragDropType = FCutDragDropBase::EType::TrackClip; Operation->VideoCapture = &VideoCapture; + Operation->MainInterface = MainInterface; + + Operation->VirtualDraggingShow = SNew(SBox) + .WidthOverride(80) + .HeightOverride(80) + .HAlign(HAlign_Fill) + .VAlign(VAlign_Fill) + [ + SNew(SImage).Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath(PropertyData.IconPath), {})) + ]; + return FReply::Handled().BeginDragDrop(Operation.ToSharedRef()); } diff --git a/Source/Cut5/Widgets/SCustomInputResource.h b/Source/Cut5/Widgets/SCustomInputResource.h index 2177f40..854d18e 100644 --- a/Source/Cut5/Widgets/SCustomInputResource.h +++ b/Source/Cut5/Widgets/SCustomInputResource.h @@ -18,7 +18,7 @@ public: } SLATE_ARGUMENT(FTimelinePropertyData, PropertyData) SLATE_ARGUMENT(cv::VideoCapture, VideoCapture) - SLATE_ARGUMENT(FString, CustomPresetName) + SLATE_ARGUMENT(ICutMainWidgetInterface*, MainInterface) SLATE_EVENT(FOnCheckBoxChecked, OnCheckBoxChecked) SLATE_END_ARGS() @@ -27,7 +27,7 @@ public: void Construct(const FArguments& InArgs); virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; virtual FReply OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; - + ICutMainWidgetInterface* MainInterface; void ShowCheckBox(bool bShow); FOnCheckBoxChecked OnCheckBoxChecked; TSharedPtr ImageOverlay; @@ -35,5 +35,4 @@ public: TSharedPtr CheckBox; TSharedPtr Box; - FString CustomPresetName; }; diff --git a/Source/Cut5/Widgets/SCutMainWindow.cpp b/Source/Cut5/Widgets/SCutMainWindow.cpp index d020b99..7099684 100644 --- a/Source/Cut5/Widgets/SCutMainWindow.cpp +++ b/Source/Cut5/Widgets/SCutMainWindow.cpp @@ -24,7 +24,7 @@ #include "DragDropOperator/DragDropOperator.h" #include "FX/SEffectCardsPanel.h" #include "HAL/FileManagerGeneric.h" -#include "Interfaces/IMainFrameModule.h" +#include "Kismet/KismetSystemLibrary.h" #include "MicroWidgets/SColorPanel.h" #include "MicroWidgets/SNewProjectTips.h" #include "StatePanel/SStatePanel.h" @@ -49,11 +49,11 @@ void SCutMainWindow::Construct(const FArguments& InArgs) MainBarTextStyle.SetFontSize(14); FTextBlockStyle TitleBarTextStyle = FAppStyle::GetWidgetStyle("NormalText"); TitleBarTextStyle.SetFontSize(15); - - + + ChildSlot [ - SNew(SOverlay) + SAssignNew(Overlay, SOverlay) + SOverlay::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) @@ -134,6 +134,12 @@ void SCutMainWindow::Construct(const FArguments& InArgs) [ SNew(SImage) .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("minus.png"), { 24, 24 })) + .OnMouseButtonDown_Lambda([](const FGeometry& Geometry, const FPointerEvent& MouseEvent) + { + // Maximize + GEngine->GameViewport->GetWindow()->Minimize(); + return FReply::Handled(); + }) ] ] + SHorizontalBox::Slot() @@ -147,6 +153,20 @@ void SCutMainWindow::Construct(const FArguments& InArgs) [ SNew(SImage) .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("Max.png"), { 24, 24 })) + .OnMouseButtonDown_Lambda([](const FGeometry& Geometry, const FPointerEvent& MouseEvent) + { + // Maximize + if (GEngine->GameViewport->GetWindow()->IsWindowMaximized()) + { + GEngine->GameViewport->GetWindow()->Restore(); + } + else + { + GEngine->GameViewport->GetWindow()->Maximize(); + } + + return FReply::Handled(); + }) ] ] + SHorizontalBox::Slot() @@ -160,6 +180,11 @@ void SCutMainWindow::Construct(const FArguments& InArgs) [ SNew(SImage) .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("Close.png"), { 24, 24 })) + .OnMouseButtonDown_Lambda([](const FGeometry& Geometry, const FPointerEvent& MouseEvent) + { + UKismetSystemLibrary::QuitGame(GWorld->GetWorld(), nullptr, EQuitPreference::Quit, false); + return FReply::Handled(); + }) ] ] ] @@ -332,30 +357,36 @@ void SCutMainWindow::Construct(const FArguments& InArgs) ]; + + + const TSharedPtr NewWidget = SNew(SBox).WidthOverride(48).HeightOverride(48) [ SNew(SImage).Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath(TEXT("MouseCursor.png")), {48, 48})) ]; GEngine->GameViewport->AddSoftwareCursorFromSlateWidget(EMouseCursor::Type::Default, NewWidget.ToSharedRef()); + + + FShortCutCommands::Register(); const FName ContextName = FShortCutCommands::Get().GetContextName(); + CommandList = MakeShared(); - IMainFrameModule& MainFrame = FModuleManager::GetModuleChecked("MainFrame"); - FInputBindingManager::Get().RegisterCommandList(ContextName, MainFrame.GetMainFrameCommandBindings()); - MainFrame.GetMainFrameCommandBindings()->MapAction(FShortCutCommands::Get().LeftPerFrame, FExecuteAction::CreateLambda([this]() + + CommandList->MapAction(FShortCutCommands::Get().LeftPerFrame, FExecuteAction::CreateLambda([this]() { CutTimeline->UpdateCursorPosition(CutTimeline->TimelineTick->GetCursorPosition() - 1); - })); - MainFrame.GetMainFrameCommandBindings()->MapAction(FShortCutCommands::Get().RightPerFrame, FExecuteAction::CreateLambda([this]() + }), EUIActionRepeatMode::RepeatEnabled); + CommandList->MapAction(FShortCutCommands::Get().RightPerFrame, FExecuteAction::CreateLambda([this]() { CutTimeline->UpdateCursorPosition(CutTimeline->TimelineTick->GetCursorPosition() + 1); - })); - MainFrame.GetMainFrameCommandBindings()->MapAction(FShortCutCommands::Get().PlayFrame, FExecuteAction::CreateLambda([this]() + }), EUIActionRepeatMode::RepeatEnabled); + CommandList->MapAction(FShortCutCommands::Get().PlayFrame, FExecuteAction::CreateLambda([this]() { CutTimeline->SetAutoPlay(!CutTimeline->AutoPlaying); })); - MainFrame.GetMainFrameCommandBindings()->MapAction(FShortCutCommands::Get().Delete, FExecuteAction::CreateLambda([this]() + CommandList->MapAction(FShortCutCommands::Get().Delete, FExecuteAction::CreateLambda([this]() { for (int32 i = 0; i < CutTimeline->SelectedClips.Num(); i++) { @@ -374,7 +405,7 @@ void SCutMainWindow::Construct(const FArguments& InArgs) } })); - MainFrame.GetMainFrameCommandBindings()->MapAction(FShortCutCommands::Get().ExportXML, FExecuteAction::CreateLambda([this]() + CommandList->MapAction(FShortCutCommands::Get().ExportXML, FExecuteAction::CreateLambda([this]() { FString String; IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get(); @@ -383,14 +414,14 @@ void SCutMainWindow::Construct(const FArguments& InArgs) return; ExportProject(String); })); - MainFrame.GetMainFrameCommandBindings()->MapAction(FShortCutCommands::Get().ZoomInTimeline, FExecuteAction::CreateLambda([this]() + CommandList->MapAction(FShortCutCommands::Get().ZoomInTimeline, FExecuteAction::CreateLambda([this]() { const float NewValue = CutTimeline->ZoomSlider->GetValue() + 0.1; CutTimeline->ZoomSlider->SetValue(NewValue); FGlobalData::DefaultTimeTickSpace = FMath::GetMappedRangeValueClamped(FVector2D(0, 1.0), FVector2D(GetCachedGeometry().GetLocalSize().X / FGlobalData::TrackLength, 14), NewValue); CutTimeline->RenderGroup(); })); - MainFrame.GetMainFrameCommandBindings()->MapAction(FShortCutCommands::Get().ZoomOutTimeline, FExecuteAction::CreateLambda([this]() + CommandList->MapAction(FShortCutCommands::Get().ZoomOutTimeline, FExecuteAction::CreateLambda([this]() { const float NewValue = CutTimeline->ZoomSlider->GetValue() - 0.1; CutTimeline->ZoomSlider->SetValue(NewValue); @@ -398,7 +429,7 @@ void SCutMainWindow::Construct(const FArguments& InArgs) CutTimeline->RenderGroup(); })); - MainFrame.GetMainFrameCommandBindings()->MapAction(FShortCutCommands::Get().SelectMode, FExecuteAction::CreateLambda([this]() + CommandList->MapAction(FShortCutCommands::Get().SelectMode, FExecuteAction::CreateLambda([this]() { SelectMode = ESelectMode::SelectMode; const TSharedPtr NewWidget = SNew(SBox).WidthOverride(48).HeightOverride(48) @@ -407,7 +438,7 @@ void SCutMainWindow::Construct(const FArguments& InArgs) ]; GEngine->GameViewport->AddSoftwareCursorFromSlateWidget(EMouseCursor::Type::Default, NewWidget.ToSharedRef()); })); - MainFrame.GetMainFrameCommandBindings()->MapAction(FShortCutCommands::Get().CutMode, FExecuteAction::CreateLambda([this]() + CommandList->MapAction(FShortCutCommands::Get().CutMode, FExecuteAction::CreateLambda([this]() { SelectMode = ESelectMode::CutMode; @@ -424,7 +455,6 @@ void SCutMainWindow::Construct(const FArguments& InArgs) FMainMenuCommands::Register(); - CommandList = MakeShareable(new FUICommandList); CommandList->MapAction(FMainMenuCommands::Get().ExportXML, FExecuteAction::CreateLambda([this]() { FString String; @@ -452,14 +482,21 @@ void SCutMainWindow::Construct(const FArguments& InArgs) { SaveProject(); })); - - - // CommandList->MapAction(FMainMenuCommands::Get().Exit, FExecuteAction::CreateLambda([this]() - // { - // FPlatformMisc::RequestExit(true); - // })); - + + CommandList->MapAction(FShortCutCommands::Get().TimelineMoveLeft, FExecuteAction::CreateLambda([this]() + { + if (CutTimeline->TrackBodyHScrollBox->GetScrollOffset() < CutTimeline->TrackBodyHScrollBox->GetScrollOffsetOfEnd()) + CutTimeline->TrackBodyHScrollBox->SetScrollOffset(CutTimeline->TrackBodyHScrollBox->GetScrollOffset() - 10); + })); + CommandList->MapAction(FShortCutCommands::Get().TimelineMoveRight, FExecuteAction::CreateLambda([this]() + { + if (CutTimeline->TrackBodyHScrollBox->GetScrollOffset() < CutTimeline->TrackBodyHScrollBox->GetScrollOffsetOfEnd()) + CutTimeline->TrackBodyHScrollBox->SetScrollOffset(CutTimeline->TrackBodyHScrollBox->GetScrollOffset() + 10); + })); + FInputBindingManager::Get().RegisterCommandList(FShortCutCommands::Get().GetContextName(), CommandList.ToSharedRef()); OnUpdateProjector(0, true); + + DragDropOperator::GetDragDropOperator()->SavedMainInterface = this; } void SCutMainWindow::Render() @@ -494,11 +531,25 @@ void SCutMainWindow::Render() +} + +void SCutMainWindow::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) +{ + if (TotalTime > 20.0f) + { + if (CutTimeline->AutoPlaying == false) + { + SaveProject(); + } + + TotalTime = 0; + } + TotalTime += InDeltaTime; } int32 SCutMainWindow::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, - const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, - const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const + const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, + const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const { if (CutTimeline && bRenderLine) { @@ -534,6 +585,7 @@ FReply SCutMainWindow::OnDragOver(const FGeometry& MyGeometry, const FDragDropEv FReply SCutMainWindow::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) { TSharedPtr DragDropOperation = DragDropEvent.GetOperationAs(); + DragDropOperator::GetDragDropOperator()->CloseCursorDecorator(); if (DragDropOperation->DragDropType == FCutDragDropBase::EType::SelectClips) { DragDropOperator::GetDragDropOperator()->OnDrop(MyGeometry, DragDropEvent, nullptr); @@ -656,6 +708,7 @@ void SCutMainWindow::AddNewCard(FEffectCardProperty& CardProperty, FString Group void SCutMainWindow::OpenTimeline(const FString& TimelineName, bool NeedSaveBefore, bool ForceOpen) { + if (NeedSaveBefore) { if (TimelineName != "") @@ -664,17 +717,23 @@ void SCutMainWindow::OpenTimeline(const FString& TimelineName, bool NeedSaveBefo { CutTimeline->SaveTimeline(FUtils::MainSaveFullPath(), CutTimeline->TimelineInfo); CutTimeline->TimelineInfo.CurrentOpenFullPath = FUtils::MainSaveFullPath(); + CutTimeline->bNeedShowPanel = false; } else { if (CutTimeline->TimelineInfo.CurrentOpenFullPath != FUtils::MainSaveFullPath()) + { CutTimeline->SaveTimeline(CutTimeline->TimelineInfo.CurrentOpenFullPath, CutTimeline->TimelineInfo); + CutTimeline->bNeedShowPanel = true; + } + else { if (!ForceOpen) { CutTimeline->SaveTimeline(FUtils::MainSaveFullPath(), CutTimeline->TimelineInfo); CutTimeline->TimelineInfo.CurrentOpenFullPath = FUtils::MainSaveFullPath(); + CutTimeline->bNeedShowPanel = false; } } @@ -684,7 +743,7 @@ void SCutMainWindow::OpenTimeline(const FString& TimelineName, bool NeedSaveBefo FTimelineInfo TimelineInfo; // 拿到TimelineName路径中的名字,也就是倒数第四位开始,去掉后缀 - + // GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TimelineName); if (CutTimeline->LoadTimeline(TimelineName, TimelineInfo)) { CutTimeline->TimelineInfo = TimelineInfo; @@ -736,11 +795,18 @@ void SCutMainWindow::OpenProject(const FString& Project) { FTimelinePropertyData TimelinePropertyData; Reader << TimelinePropertyData; - FTimelinePropertyData ReloadPropertyData; - FFFMPEGUtils::LoadMedia(TimelinePropertyData.MoviePath, &ReloadPropertyData); - ReloadPropertyData.Guid = TimelinePropertyData.Guid; + + FTimelinePropertyData ReloadPropertyData = TimelinePropertyData; + if (TimelinePropertyData.bIsCustomPresetData == false) + { + if (FFFMPEGUtils::LoadMedia(TimelinePropertyData.MoviePath, &ReloadPropertyData) == TEXT("Failed")) + { + continue; + } + ReloadPropertyData.Guid = TimelinePropertyData.Guid; + } - CustomInputPanel->GridPanel->AddSlot(CustomInputPanel->GetChildren()->Num() % 2, CustomInputPanel->GetChildren()->Num() / 2) + CustomInputPanel->GridPanel->AddSlot(i % 2, i / 2) [ SNew(SCustomInputResource) .PropertyData(ReloadPropertyData) @@ -1161,8 +1227,9 @@ void SCutMainWindow::AddNewCustomPreset(const FString& Name, const FPresetsCusto FTimelinePropertyData NewPropertyData; NewPropertyData.bIsCustomPresetData = true; NewPropertyData.PresetsCustomData = CustomData; - - TSharedPtr CustomInputResource = SNew(SCustomInputResource).PropertyData(NewPropertyData).CustomPresetName(Name); + NewPropertyData.Name = Name; + + TSharedPtr CustomInputResource = SNew(SCustomInputResource).PropertyData(NewPropertyData); CustomInputPanel->GridPanel->AddSlot(CustomInputPanel->GridPanel->GetChildren()->Num() % 2, CustomInputPanel->GridPanel->GetChildren()->Num() / 2) [ CustomInputResource.ToSharedRef() @@ -1177,6 +1244,33 @@ ESelectMode SCutMainWindow::GetSelectedMode() return SelectMode; } +FReply SCutMainWindow::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent) +{ + if (CommandList->ProcessCommandBindings(InKeyEvent)) + { + return FReply::Handled(); + } + return FReply::Handled(); +} + +FReply SCutMainWindow::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) +{ + if (CommandList->ProcessCommandBindings(MouseEvent)) + { + return FReply::Handled(); + } + return FReply::Handled(); +} + +FReply SCutMainWindow::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) +{ + if (CommandList->ProcessCommandBindings(MouseEvent)) + { + return FReply::Handled(); + } + return FReply::Handled(); +} + tinyxml2::XMLElement* SCutMainWindow::GetDeviceElement(tinyxml2::XMLElement* Parent) { tinyxml2::XMLElement* Device = Parent->InsertNewChildElement("Device"); @@ -1498,7 +1592,7 @@ tinyxml2::XMLElement* SCutMainWindow::GetSpecialEffectList(tinyxml2::XMLElement* } for (int32 j = 0; j < EffectCardsPanel->EffectCardGroups[i].Cards.Num(); j++) { - OpenTimeline(FUtils::SingleCardFullPath(EffectCardsPanel->EffectCardGroups[i].Cards[j].Name), true, true); + OpenTimeline(FUtils::SingleCardFullPath(EffectCardsPanel->EffectCardGroups[i].Cards[j].Guid.ToString()), true, true); CurrentSelectedPropertiesInterfaceGuid = EffectCardsPanel->EffectCardGroups[i].Cards[j].Guid; // OnSelectCard(EffectCardsPanel->EffectCardGroups[i].Cards[j].Guid); GetSpecialEffect(SpecialEffectsList, &EffectCardsPanel->EffectCardGroups[i].Cards[j]); diff --git a/Source/Cut5/Widgets/SCutMainWindow.h b/Source/Cut5/Widgets/SCutMainWindow.h index 9c7da14..4b50215 100644 --- a/Source/Cut5/Widgets/SCutMainWindow.h +++ b/Source/Cut5/Widgets/SCutMainWindow.h @@ -41,15 +41,18 @@ public: TSharedPtr EffectCardsPanel; TArray> PlayerLightsSlateInstances; TSharedPtr DefaultCursorWidget; + TSharedPtr Overlay; TSharedPtr CommandList; void Render(); - + virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override; virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override; virtual FReply OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override; virtual FReply OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override; FSoundThread* SoundThread; + + float TotalTime; bool bRenderLine = false; float RenderLineTime = 0; @@ -85,6 +88,11 @@ public: virtual void OpenColorPanel(FLinearColor* ColorPtr); virtual void AddNewCustomPreset(const FString& Name, const FPresetsCustomData CustomData) override; virtual ESelectMode GetSelectedMode() override; + + virtual bool SupportsKeyboardFocus() const override { return true; }; + virtual FReply OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent) override; + virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; + virtual FReply OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; tinyxml2::XMLElement* GetDeviceElement(tinyxml2::XMLElement* Parent); tinyxml2::XMLElement* GetVideoElement(tinyxml2::XMLElement* Parent, FEncodeVideoInfo EncodeVideoInfo); diff --git a/Source/Cut5/Widgets/SCutTimeline.cpp b/Source/Cut5/Widgets/SCutTimeline.cpp index 7b68513..22c3679 100644 --- a/Source/Cut5/Widgets/SCutTimeline.cpp +++ b/Source/Cut5/Widgets/SCutTimeline.cpp @@ -106,7 +106,7 @@ void SCutTimeline::Construct(const FArguments& InArgs) ] + SOverlay::Slot() .HAlign(HAlign_Fill) - .VAlign(VAlign_Fill) + .VAlign(VAlign_Top) [ SNew(SVerticalBox) + SVerticalBox::Slot() @@ -115,7 +115,7 @@ void SCutTimeline::Construct(const FArguments& InArgs) // Tool bar SNew(SHorizontalBox) + SHorizontalBox::Slot() - + .SizeParam(FAuto()) .Padding(8, 0, 0, 0) .HAlign(HAlign_Left) .VAlign(VAlign_Center) @@ -205,6 +205,7 @@ void SCutTimeline::Construct(const FArguments& InArgs) ] + SVerticalBox::Slot() + .SizeParam(FStretch(1.0)) [ // Timeline SNew(SHorizontalBox) @@ -265,7 +266,7 @@ void SCutTimeline::Construct(const FArguments& InArgs) [ SAssignNew(TimelineTickBox, SBox) .WidthOverride(FGlobalData::TrackLength * FGlobalData::DefaultTimeTickSpace) - .HeightOverride(25) + .MaxDesiredHeight(60) [ SAssignNew(TickScrollBox, SScrollBox) .ScrollBarVisibility(EVisibility::Hidden) @@ -514,7 +515,10 @@ void SCutTimeline::RenderGroup() FTextBlockStyle BlackHugeText = FAppStyle::GetWidgetStyle("NormalText"); BlackHugeText.SetFontSize(16); - + if (!bNeedShowPanel) + { + return; + } for (int32 i = 0; i < DeviceTrackGroups.Num(); i++) { @@ -668,7 +672,9 @@ bool SCutTimeline::LoadTimeline(const FString& LoadPath, FTimelineInfo& Info) { if (StaticCastSharedPtr(TrackGroupInstances[l].Head)->TrackData.DeviceTrack.Guid == DeviceTrackGroups[j].DeviceTracks[k].Guid) { + AllClips[i].MovieBrushes = FFFMPEGUtils::GetMovieBrush(&AllClips[i], false); + AllClips[i].AudioBrushes = FFFMPEGUtils::GetAudioBrush(&AllClips[i]); StaticCastSharedPtr(TrackGroupInstances[l].Head)->TrackData.ClipData.Add(AllClips[i]); } } @@ -773,8 +779,16 @@ void SCutTimeline::AddNewDeviceToGroup(FString GroupName, FDeviceTrack DeviceTra TrackData.TrackName = DeviceTrack.DeviceName; TrackData.TrackType = DeviceTrack.DeviceType; TrackData.DeviceTrack = DeviceTrack; + + + AddNewTrack(TrackData, 0, GroupName); RenderGroup(); + + if (DeviceTrack.DeviceType == ETrackType::AtomSphereLightTrack) + { + MainWidgetInterface->OnAddNewTrack(ETrackType::PlayerTrack); + } } END_SLATE_FUNCTION_BUILD_OPTIMIZATION diff --git a/Source/Cut5/Widgets/SCutTimeline.h b/Source/Cut5/Widgets/SCutTimeline.h index 179efd0..582f82e 100644 --- a/Source/Cut5/Widgets/SCutTimeline.h +++ b/Source/Cut5/Widgets/SCutTimeline.h @@ -131,6 +131,8 @@ public: bool bRenderBox = false; TArray RenderBoxPos {{}, {}}; + + bool bNeedShowPanel = false; }; diff --git a/Source/Cut5/Widgets/SStartMenu.cpp b/Source/Cut5/Widgets/SStartMenu.cpp index 8265261..0637ca1 100644 --- a/Source/Cut5/Widgets/SStartMenu.cpp +++ b/Source/Cut5/Widgets/SStartMenu.cpp @@ -20,11 +20,15 @@ void SStartMenu::Construct(const FArguments& InArgs) + SOverlay::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) + .Padding(16, 47, 16, 16) [ SNew(SImage) .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath(TEXT("BackGround.png")), {})) ] + SOverlay::Slot() + .HAlign(HAlign_Fill) + .VAlign(VAlign_Fill) + .Padding(16, 47, 16, 16) [ SNew(SVerticalBox) + SVerticalBox::Slot() diff --git a/Source/Cut5/Widgets/STimelineClip.cpp b/Source/Cut5/Widgets/STimelineClip.cpp index 9a3faad..b5557d3 100644 --- a/Source/Cut5/Widgets/STimelineClip.cpp +++ b/Source/Cut5/Widgets/STimelineClip.cpp @@ -55,25 +55,12 @@ FReply STimelineClip::OnBorderMouseButtonDown(const FGeometry& Geometry, const F return FReply::Handled(); } - // if (ClipData->PresetType != EPresetType::NotAPresets) - // { - // for (int32 i = 0; i < ClipData->Cursors.Num(); i++) - // { - // TSharedPtr 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()); const float DragOffset = MainWidgetInterface->GetCutTimeline()->GetCachedGeometry().AbsoluteToLocal(PointerEvent.GetScreenSpacePosition()).X; if (LocalPos.X <= 10) { - if (ClipData->bCanDrag) + if (ClipData->bCanDrag && !MainWidgetInterface->GetCutTimeline()->SelectedClips.Contains(ClipData->ClipGuid)) { const TSharedPtr Clip2ClipDragDropOperation = MakeShared(); Clip2ClipDragDropOperation->TrackBody = StaticCastSharedPtr(Body); @@ -88,7 +75,7 @@ FReply STimelineClip::OnBorderMouseButtonDown(const FGeometry& Geometry, const F } if (LocalPos.X >= Geometry.GetLocalSize().X - 10) { - if (ClipData->bCanDrag) + if (ClipData->bCanDrag && !MainWidgetInterface->GetCutTimeline()->SelectedClips.Contains(ClipData->ClipGuid)) { const TSharedPtr Clip2ClipDragDropOperation = MakeShared(); Clip2ClipDragDropOperation->TrackBody = StaticCastSharedPtr(Body); @@ -690,7 +677,17 @@ void STimelineClip::UpdateMove(int32 X, int32 DragOffset) FReply STimelineClip::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) { const FVector2D LocalPos = MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()); - + bNeedPaintDrag = false; + if (LocalPos.X <= 10) + { + bNeedPaintDrag = true; + PaintDragType = 0; + } + if (LocalPos.X >= MyGeometry.GetLocalSize().X - 10) + { + bNeedPaintDrag = true; + PaintDragType = 1; + } return FReply::Handled(); } @@ -700,28 +697,50 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe { const float XLength = AllottedGeometry.GetLocalSize().X; + const float TotalLength = ((ClipData->ClipEndFrame - ClipData->ClipStartFrame) * FGlobalData::DefaultTimeTickSpace); { - - const float TotalLength = ((ClipData->ClipEndFrame - ClipData->ClipStartFrame) * FGlobalData::DefaultTimeTickSpace); + if (ClipData->AudioBrushes.Num() > 0) { int32 i = 0; const int32 PicLength = TotalLength / ClipData->AudioBrushes.Num(); for (FSlateBrush& SlateBrush : ClipData->AudioBrushes) { - FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 2, AllottedGeometry.ToPaintGeometry(FVector2f(PicLength, AllottedGeometry.GetLocalSize().Y), FSlateLayoutTransform(FVector2f(i * PicLength, 0))), &SlateBrush); + FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 3, AllottedGeometry.ToPaintGeometry(FVector2f(PicLength, AllottedGeometry.GetLocalSize().Y), FSlateLayoutTransform(FVector2f(i * PicLength, 0))), &SlateBrush); i++; } } } - + if (ClipData->MovieBrushes.Num() > 0) { - int32 i = 0; - for (FSlateBrush& SlateBrush : ClipData->MovieBrushes) + + int32 Step = ClipData->MovieBrushes.Num(); + const int32 PerImageLength = TotalLength / ClipData->MovieBrushesPath.Num(); + const int32 ShouldPerImageLength = TotalLength / 128; + if (ShouldPerImageLength != 0) { - FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 3, AllottedGeometry.ToPaintGeometry(FVector2f(XLength / ClipData->MovieBrushes.Num(), AllottedGeometry.GetLocalSize().Y), FSlateLayoutTransform(FVector2f(i * (XLength / ClipData->MovieBrushes.Num()), 0))), &SlateBrush); + Step = ClipData->MovieBrushes.Num() / ShouldPerImageLength; + } + + + TArray NewBrushes; + int32 Current = 0; + for (int32 j = 0; j < ShouldPerImageLength; j++) + { + if (ClipData->MovieBrushes.Num() > 0) + NewBrushes.Add(ClipData->MovieBrushes[Current]); + Current += Step; + } + int32 i = 0; + if (NewBrushes.Num() == 0) + { + NewBrushes.Add(ClipData->MovieBrushes[0]); + } + for (FSlateBrush& SlateBrush : NewBrushes) + { + FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 3, AllottedGeometry.ToPaintGeometry(FVector2f(XLength / NewBrushes.Num(), AllottedGeometry.GetLocalSize().Y), FSlateLayoutTransform(FVector2f(i * (XLength / NewBrushes.Num()), 0))), &SlateBrush); i++; } } @@ -730,11 +749,11 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe if (ClipData->PresetType == EPresetType::EnableProjector) { - FSlateDrawElement::MakeText(OutDrawElements, LayerId + 2, AllottedGeometry.ToPaintGeometry(), FText::FromString(TEXT("开启投影仪")), FAppStyle::Get().GetWidgetStyle("NormalText").Font, ESlateDrawEffect::None, FLinearColor::White); + FSlateDrawElement::MakeText(OutDrawElements, LayerId + 3, AllottedGeometry.ToPaintGeometry(), FText::FromString(TEXT("开启投影仪")), FAppStyle::Get().GetWidgetStyle("NormalText").Font, ESlateDrawEffect::None, FLinearColor::White); } if (ClipData->PresetType == EPresetType::DisableProjector) { - FSlateDrawElement::MakeText(OutDrawElements, LayerId + 2, AllottedGeometry.ToPaintGeometry(), FText::FromString(TEXT("关闭投影仪")), FAppStyle::Get().GetWidgetStyle("NormalText").Font, ESlateDrawEffect::None, FLinearColor::White); + FSlateDrawElement::MakeText(OutDrawElements, LayerId + 3, AllottedGeometry.ToPaintGeometry(), FText::FromString(TEXT("关闭投影仪")), FAppStyle::Get().GetWidgetStyle("NormalText").Font, ESlateDrawEffect::None, FLinearColor::White); } @@ -746,7 +765,7 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe Vectors.Add(FVector2f(0, AllottedGeometry.Size.Y)); Vectors.Add(FVector2f(AllottedGeometry.Size.X, AllottedGeometry.Size.Y)); Vectors.Add(FVector2f(AllottedGeometry.Size.X, 0)); - FSlateDrawElement::MakeLines(OutDrawElements, LayerId + 2, AllottedGeometry.ToPaintGeometry(), Vectors, ESlateDrawEffect::None, FLinearColor::White, true, 2.0f); + FSlateDrawElement::MakeLines(OutDrawElements, LayerId + 3, AllottedGeometry.ToPaintGeometry(), Vectors, ESlateDrawEffect::None, FLinearColor::White, true, 2.0f); return SCompoundWidget::OnPaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId + 1, InWidgetStyle, bParentEnabled); } @@ -782,7 +801,7 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe if (ClipData->PresetType == EPresetType::Color) { const FSlateBrush Brush; - FSlateDrawElement::MakeBox(OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), + FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 3, AllottedGeometry.ToPaintGeometry(), &Brush, ESlateDrawEffect::None, ClipData->ClipColors[0]); } if (ClipData->PresetType == EPresetType::Gradient) @@ -799,6 +818,22 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe EOrientation::Orient_Vertical, ESlateDrawEffect::None); } + if (bNeedPaintDrag) + { + if (PaintDragType == 0) + { + const FSlateBrush Brush; + FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 3, AllottedGeometry.ToPaintGeometry(FVector2f(10, AllottedGeometry.Size.Y), FSlateLayoutTransform(FVector2f(0, 0))), + &Brush, ESlateDrawEffect::None, FLinearColor(1.0, 0.0, 1.0, 1.0)); + } + else if (PaintDragType == 1) + { + const FSlateBrush Brush; + FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 3, AllottedGeometry.ToPaintGeometry(FVector2f(10, AllottedGeometry.Size.Y), FSlateLayoutTransform(FVector2f(AllottedGeometry.Size.X - 10, 0))), + &Brush, ESlateDrawEffect::None, FLinearColor(1.0, 0.0, 1.0, 1.0)); + } + + } return SCompoundWidget::OnPaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId + 1, InWidgetStyle, @@ -817,9 +852,12 @@ void STimelineClip::DoSound(ESoundSolveType SolveType, int32 InFrame) { if (SoundThread == nullptr) { - SoundThread = new FSoundThread(2, ClipData->ResourcePropertyDataPtr->AudioSample); - FRunnableThread* Thread = FRunnableThread::Create(SoundThread, TEXT("SoundThread")); - SoundThread->CopyAudio(ClipData->ResourcePropertyDataPtr->AudioData.GetData(), ClipData->ResourcePropertyDataPtr->AudioData.Num(), SolveType); + if (ClipData->ResourcePropertyDataPtr->AudioStream != -1) + { + SoundThread = new FSoundThread(2, ClipData->ResourcePropertyDataPtr->AudioSample); + FRunnableThread* Thread = FRunnableThread::Create(SoundThread, TEXT("SoundThread")); + SoundThread->CopyAudio(ClipData->ResourcePropertyDataPtr->AudioData.GetData(), ClipData->ResourcePropertyDataPtr->AudioData.Num(), SolveType); + } } const int32 Offset = InFrame - ClipData->ClipStartFrame; const int32 SeekMovieFrame = ClipData->VideoStartFrame + Offset; @@ -840,5 +878,17 @@ void STimelineClip::OnDragLeave(const FDragDropEvent& DragDropEvent) bIsDragOver = false; } +void STimelineClip::OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) +{ + SCompoundWidget::OnMouseEnter(MyGeometry, MouseEvent); + +} + +void STimelineClip::OnMouseLeave(const FPointerEvent& MouseEvent) +{ + SCompoundWidget::OnMouseLeave(MouseEvent); + bNeedPaintDrag = false; +} + END_SLATE_FUNCTION_BUILD_OPTIMIZATION diff --git a/Source/Cut5/Widgets/STimelineClip.h b/Source/Cut5/Widgets/STimelineClip.h index 2ae6366..0a20dc7 100644 --- a/Source/Cut5/Widgets/STimelineClip.h +++ b/Source/Cut5/Widgets/STimelineClip.h @@ -63,6 +63,12 @@ public: virtual void OnDragEnter(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override; virtual void OnDragLeave(const FDragDropEvent& DragDropEvent) override; + virtual void OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; + virtual void OnMouseLeave(const FPointerEvent& MouseEvent) override; + + bool bNeedPaintDrag = false; + int32 PaintDragType = 0; + bool bIsDragOver = false; }; diff --git a/Source/Cut5/Widgets/STimelinePropertyPanel.cpp b/Source/Cut5/Widgets/STimelinePropertyPanel.cpp index d0d7646..9b5024a 100644 --- a/Source/Cut5/Widgets/STimelinePropertyPanel.cpp +++ b/Source/Cut5/Widgets/STimelinePropertyPanel.cpp @@ -73,7 +73,7 @@ void STimelinePropertyPanel::Construct(const FArguments& InArgs) } } FDeviceTrack DeviceTrack(TEXT("玩家"), ETrackType::AtomSphereLightTrack); - MainWindow->CutTimeline->AddNewDeviceToGroup(TEXT("角色组") + FString::FromInt(Index), DeviceTrack, ETrackType::PlayerTrack); + MainWindow->CutTimeline->AddNewDeviceToGroup(TEXT("角色组") + FString::FromInt(Index), DeviceTrack, ETrackType::AtomSphereLightTrack); return FReply::Handled(); }) ] diff --git a/Source/Cut5/Widgets/STimelineTick.cpp b/Source/Cut5/Widgets/STimelineTick.cpp index fe4587b..fa57bd7 100644 --- a/Source/Cut5/Widgets/STimelineTick.cpp +++ b/Source/Cut5/Widgets/STimelineTick.cpp @@ -6,6 +6,8 @@ #include "AudioDevice.h" #include "DefineGlobal.h" #include "SlateOptMacros.h" +#include "Cut5/Utils/Utils.h" +#include "Rendering/SlateDrawBuffer.h" BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION @@ -65,7 +67,7 @@ int32 STimelineTick::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe ESlateDrawEffect::None, FColor(55, 55, 55, 255)); } - if (j % 10 == 0) + if (j % 30 == 0) { const FSlateBrush Brush; FSlateDrawElement::MakeBox( @@ -75,6 +77,11 @@ int32 STimelineTick::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe &Brush, ESlateDrawEffect::None, FColor(95, 95, 95, 255)); + const FPaintGeometry NewTextLoc = AllottedGeometry.ToPaintGeometry(FVector2f(2, TickBox->GetCachedGeometry().GetLocalSize().Y + 2) + , FSlateLayoutTransform(FVector2f(TickBox->GetCachedGeometry().GetLocalPositionAtCoordinates(FVector2f(0.0, 0.0)).X + j * FGlobalData::DefaultTimeTickSpace, 5))); + FSlateDrawElement::MakeText( + OutDrawElements, LayerId, NewTextLoc, FGlobalData::GetTimeData(j), FAppStyle::Get().GetWidgetStyle("NormalText").Font, ESlateDrawEffect::None, FLinearColor(1.0, 1.0, 1.0, 0.5)); + } } diff --git a/Source/Cut5/Widgets/StatePanel/SStatePanel.cpp b/Source/Cut5/Widgets/StatePanel/SStatePanel.cpp index f803cf1..6a3aef1 100644 --- a/Source/Cut5/Widgets/StatePanel/SStatePanel.cpp +++ b/Source/Cut5/Widgets/StatePanel/SStatePanel.cpp @@ -189,13 +189,22 @@ void SStatePanel::Construct(const FArguments& InArgs) .WidthOverride(100) .HeightOverride(60) [ - SNew(SButton) + SAssignNew(SwitchButton, SButton) .OnClicked_Lambda([this]() { ShowSwitcher->SetActiveWidgetIndex(!bIsVideo); bIsVideo = !bIsVideo; + if (bIsVideo) + { + SwitchButton->SetContent(VideoPlayer.ToSharedRef()); + } + else + { + SwitchButton->SetContent(LightArray.ToSharedRef()); + } return FReply::Handled(); }) + ] ] @@ -226,7 +235,7 @@ void SStatePanel::Construct(const FArguments& InArgs) ] ]; - + SwitchButton->SetContent(LightArray.ToSharedRef()); } diff --git a/Source/Cut5/Widgets/StatePanel/SStatePanel.h b/Source/Cut5/Widgets/StatePanel/SStatePanel.h index 64e581d..1fef961 100644 --- a/Source/Cut5/Widgets/StatePanel/SStatePanel.h +++ b/Source/Cut5/Widgets/StatePanel/SStatePanel.h @@ -30,6 +30,6 @@ public: TSharedPtr MainShow; TSharedPtr Projector; TSharedPtr SpotLight; - + TSharedPtr SwitchButton; bool bIsVideo = false; };