diff --git a/Source/Cut5/Widgets/DefineGlobal.h b/Source/Cut5/Widgets/DefineGlobal.h index 138001f..d6e1335 100644 --- a/Source/Cut5/Widgets/DefineGlobal.h +++ b/Source/Cut5/Widgets/DefineGlobal.h @@ -266,6 +266,8 @@ struct CUT5_API FPresetsCustomData float Angle; float Time = 0.3; EPresetCustomType PresetCustomType = EPresetCustomType::None; + + TArray Cursors; friend FArchive& operator<<(FArchive& Ar, FPresetsCustomData& PresetsData) { @@ -274,6 +276,7 @@ struct CUT5_API FPresetsCustomData Ar << PresetsData.Angle; Ar << PresetsData.Time; Ar << PresetsData.PresetCustomType; + Ar << PresetsData.Cursors; return Ar; } }; diff --git a/Source/Cut5/Widgets/STimelineClip.cpp b/Source/Cut5/Widgets/STimelineClip.cpp index 57c01e0..e381f83 100644 --- a/Source/Cut5/Widgets/STimelineClip.cpp +++ b/Source/Cut5/Widgets/STimelineClip.cpp @@ -23,6 +23,7 @@ #include "Presets/SClipCursor.h" #include "Rendering/DrawElementPayloads.h" #include "Slate/Private/Framework/Application/Menu.h" +#include "TimelineClips/ClipProxy.h" #include "Widgets/Input/SSpinBox.h" #include "Widgets/Layout/SSpacer.h" @@ -52,7 +53,8 @@ FReply STimelineClip::OnBorderMouseButtonDown(const FGeometry& Geometry, const F return FReply::Handled(); } - + TSharedPtr ClipProxy = FClipProxy::GetProxy(); + ClipProxy->UpdateInterface(this); if (MainWidgetInterface->GetSelectedMode() == ESelectMode::CutMode) { Body->SelectedClipFrame = (Geometry.AbsoluteToLocal(PointerEvent.GetScreenSpacePosition()).X) / FGlobalData::DefaultTimeTickSpace; @@ -62,8 +64,6 @@ FReply STimelineClip::OnBorderMouseButtonDown(const FGeometry& Geometry, const F MainWidgetInterface->GetCutTimeline()->SelectedClips.AddUnique(ClipData->ClipGuid); - MainWidgetInterface->UpdateProperties(nullptr); - MainWidgetInterface->UpdateProperties(this); LocalPos = Geometry.AbsoluteToLocal(PointerEvent.GetScreenSpacePosition()); const float DragOffset = MainWidgetInterface->GetCutTimeline()->GetCachedGeometry().AbsoluteToLocal(PointerEvent.GetScreenSpacePosition()).X; @@ -205,6 +205,7 @@ void STimelineClip::Construct(const FArguments& InArgs) } + } void STimelineClip::Seek(int32 Frame) @@ -1003,251 +1004,6 @@ void STimelineClip::Tick(const FGeometry& AllottedGeometry, const double InCurre TSharedPtr STimelineClip::GetPropertiesWidget() { - Selectable.Empty(); - Selectable.Add(MakeShared(TEXT("无"))); - Selectable.Add(MakeShared(TEXT("呼吸"))); - Selectable.Add(MakeShared(TEXT("闪烁"))); - Selectable.Add(MakeShared(TEXT("渐变"))); - - - FTextBlockStyle NormalText = FAppStyle::GetWidgetStyle("NormalText"); - NormalText.SetFontSize(13); - PropertiesWidget = - SNew(SVerticalBox) - + 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(SImage) - .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("Color.png"), {})) - .ColorAndOpacity_Lambda([this]() - { - if (CustomData.Colors.Num() == 0) - { - return FLinearColor(1, 1, 1, 0.5); - } - return CustomData.Colors[0]; - }) - .OnMouseButtonDown_Lambda([this](const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) - { - MainWidgetInterface->OpenColorPanel(&CustomData.Colors[0]); - return FReply::Handled(); - }) - ] - ] - ] - ] - + 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(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; - case 3: - CustomData.PresetCustomType = FPresetsCustomData::EPresetCustomType::Gradient; - default: - break; - } - }) - [ - SNew(STextBlock) - .Text_Lambda([this]() - { - return FText::FromString( CustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::None ? TEXT("无") : CustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::Breathe ? TEXT("呼吸") : TEXT("闪烁")); - }) - ] - ] - ] - ] - ] - + 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) - .Value(1) - .MinValue(1) - .OnValueChanged_Lambda([this](const int32& Value) - { - CustomData.Times = Value; - }) - ] - ] - ] - ] - + 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) - .Value(0.3) - .MinValue(0.3) - .OnValueChanged_Lambda([this](const float& Value) - { - CustomData.Time = Value; - }) - // .TypeInterface(MakeShared>(EUnit::Seconds)) - ] - ] - ] - ] - + SVerticalBox::Slot() - .SizeParam(FStretch(1.0)) - [ - SNew(SSpacer) - ] - + SVerticalBox::Slot() - .HAlign(HAlign_Center) - .VAlign(VAlign_Bottom) - .Padding(0, 0, 0, 24) - [ - SNew(SBox).HeightOverride(40).WidthOverride(144) - [ - SNew(SOverlay) - + SOverlay::Slot() - .HAlign(HAlign_Fill) - .VAlign(VAlign_Fill) - [ - SNew(SImage) - .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("SaveCustomPreset.png"), {144, 40})) - .OnMouseButtonDown_Lambda([this](const FGeometry&, const FPointerEvent&) - { - TSharedPtr NewProjectTips = SNew(SNewProjectTips).Title(TEXT("保存自定义效果名称")); - NewProjectTips->OnEnsure.BindLambda([this, NewProjectTips](const FString& String) - { - MainWidgetInterface->AddNewCustomPreset(String, CustomData); - GEngine->GameViewport->RemoveViewportWidgetContent(NewProjectTips.ToSharedRef()); - }); - GEngine->GameViewport->AddViewportWidgetContent(NewProjectTips.ToSharedRef() - , 1); - return FReply::Handled(); - }) - ] - + SOverlay::Slot() - [ - SNew(STextBlock) - .Visibility(EVisibility::HitTestInvisible) - .Text(FText::FromString((TEXT("保存自定义效果")))) - .Font(NormalText.Font) - .Justification(ETextJustify::Center) - ] - ] - ]; - // TODO: 配置文件保存自定义效果 - // TODO: 自定义效果拖拽到轨道 return PropertiesWidget; } diff --git a/Source/Cut5/Widgets/STimelineClip.h b/Source/Cut5/Widgets/STimelineClip.h index bc70f05..df32dfb 100644 --- a/Source/Cut5/Widgets/STimelineClip.h +++ b/Source/Cut5/Widgets/STimelineClip.h @@ -78,6 +78,6 @@ public: virtual TSharedPtr GetPropertiesWidget() override; TSharedPtr>> GroupComboBox; TArray> Selectable; - FPresetsCustomData CustomData; + }; diff --git a/Source/Cut5/Widgets/TimelineClips/ClipProxy.cpp b/Source/Cut5/Widgets/TimelineClips/ClipProxy.cpp new file mode 100644 index 0000000..57dea0c --- /dev/null +++ b/Source/Cut5/Widgets/TimelineClips/ClipProxy.cpp @@ -0,0 +1,286 @@ +#include "ClipProxy.h" + +#include "Cut5/Utils/Utils.h" +#include "Cut5/Widgets/STimelineClip.h" +#include "Cut5/Widgets/MicroWidgets/SNewProjectTips.h" +#include "Widgets/Input/SSpinBox.h" +#include "Widgets/Layout/SSpacer.h" + +TSharedPtr FClipProxy::GetProxy() +{ + static TSharedPtr Proxy = MakeShareable(new FClipProxy()); + return Proxy; +} + +void FClipProxy::UpdateInterface(STimelineClip* InTimeClip) +{ + this->TimelineClip = InTimeClip; + TimelineClip->MainWidgetInterface->UpdateProperties(nullptr); + TimelineClip->MainWidgetInterface->UpdateProperties(this); +} + +TSharedPtr FClipProxy::GetPropertiesWidget() +{ + Selectable.Empty(); + Selectable.Add(MakeShared(TEXT("无"))); + Selectable.Add(MakeShared(TEXT("呼吸"))); + Selectable.Add(MakeShared(TEXT("闪烁"))); + Selectable.Add(MakeShared(TEXT("渐变"))); + + + FTextBlockStyle NormalText = FAppStyle::GetWidgetStyle("NormalText"); + NormalText.SetFontSize(13); + return PropertiesWidget = + SNew(SVerticalBox) + + 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(SImage) + .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("Color.png"), {})) + .ColorAndOpacity_Lambda([this]() + { + if (TimelineClip->ClipData->PresetsCustomData.Colors.Num() == 0) + { + return FLinearColor(1, 1, 1, 0.5); + } + else + { + return TimelineClip->ClipData->PresetsCustomData.Colors[0]; + } + }) + .OnMouseButtonDown_Lambda([this](const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) + { + TimelineClip->MainWidgetInterface->OpenColorPanel(&TimelineClip->ClipData->PresetsCustomData.Colors[0]); + return FReply::Handled(); + }) + ] + ] + ] + ] + + 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(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: + TimelineClip->ClipData->PresetsCustomData.PresetCustomType = FPresetsCustomData::EPresetCustomType::None; + break; + case 1: + TimelineClip->ClipData->PresetsCustomData.PresetCustomType = FPresetsCustomData::EPresetCustomType::Breathe; + break; + case 2: + TimelineClip->ClipData->PresetsCustomData.PresetCustomType = FPresetsCustomData::EPresetCustomType::Flash; + break; + case 3: + TimelineClip->ClipData->PresetsCustomData.PresetCustomType = FPresetsCustomData::EPresetCustomType::Gradient; + default: + break; + } + }) + [ + SNew(STextBlock) + .Text_Lambda([this]() + { + return FText::FromString( TimelineClip->ClipData->PresetsCustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::None ? TEXT("无") : TimelineClip->ClipData->PresetsCustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::Breathe ? TEXT("呼吸") : TimelineClip->ClipData->PresetsCustomData.PresetCustomType == FPresetsCustomData::EPresetCustomType::Gradient ? TEXT("渐变") : TEXT("闪烁")); + }) + ] + ] + ] + ] + ] + + 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) + .Value_Lambda([this]() + { + return TimelineClip->ClipData->PresetsCustomData.Times; + }) + .MinValue(1) + .MaxValue(200) + .OnValueChanged_Lambda([this](const int32& Value) + { + TimelineClip->ClipData->PresetsCustomData.Times = Value; + }) + ] + ] + ] + ] + + 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) + .Value(0.3) + .MinValue(0.3) + .OnValueChanged_Lambda([this](const float& Value) + { + + TimelineClip->ClipData->ClipEndFrame = TimelineClip->ClipData->ClipStartFrame + Value * FGlobalData::GlobalFPS; + TimelineClip->ClipData->PresetsCustomData.Time = (TimelineClip->ClipData->ClipEndFrame - TimelineClip->ClipData->ClipStartFrame) / FGlobalData::GlobalFPS; + }) + .Value_Lambda([this]() + { + return (TimelineClip->ClipData->ClipEndFrame - TimelineClip->ClipData->ClipStartFrame) / FGlobalData::GlobalFPS; + }) + // .TypeInterface(MakeShared>(EUnit::Seconds)) + ] + ] + ] + ] + + SVerticalBox::Slot() + .SizeParam(FStretch(1.0)) + [ + + SNew(SSpacer) + ] + + SVerticalBox::Slot() + .HAlign(HAlign_Center) + .VAlign(VAlign_Bottom) + .Padding(0, 0, 0, 24) + [ + SNew(SBox).HeightOverride(40).WidthOverride(144) + [ + SNew(SOverlay) + + SOverlay::Slot() + .HAlign(HAlign_Fill) + .VAlign(VAlign_Fill) + [ + SNew(SImage) + .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("SaveCustomPreset.png"), {144, 40})) + .OnMouseButtonDown_Lambda([this](const FGeometry&, const FPointerEvent&) + { + TSharedPtr NewProjectTips = SNew(SNewProjectTips).Title(TEXT("保存自定义效果名称")); + NewProjectTips->OnEnsure.BindLambda([this, NewProjectTips](const FString& String) + { + TimelineClip->MainWidgetInterface->AddNewCustomPreset(String, TimelineClip->ClipData->PresetsCustomData); + GEngine->GameViewport->RemoveViewportWidgetContent(NewProjectTips.ToSharedRef()); + }); + GEngine->GameViewport->AddViewportWidgetContent(NewProjectTips.ToSharedRef() + , 1); + return FReply::Handled(); + }) + ] + + SOverlay::Slot() + [ + SNew(STextBlock) + .Visibility(EVisibility::HitTestInvisible) + .Text(FText::FromString((TEXT("保存自定义效果")))) + .Font(NormalText.Font) + .Justification(ETextJustify::Center) + ] + ] + ]; + // TODO: 配置文件保存自定义效果 + // TODO: 自定义效果拖拽到轨道 + + +} diff --git a/Source/Cut5/Widgets/TimelineClips/ClipProxy.h b/Source/Cut5/Widgets/TimelineClips/ClipProxy.h new file mode 100644 index 0000000..e7bcbb3 --- /dev/null +++ b/Source/Cut5/Widgets/TimelineClips/ClipProxy.h @@ -0,0 +1,18 @@ +#pragma once +#include "Cut5/Interface/PropertiesInterface.h" +#include "Widgets/Input/SComboBox.h" + + +class FClipProxy : public IPropertiesInterface +{ +public: + static TSharedPtr GetProxy(); + void UpdateInterface(class STimelineClip* InTimeClip); + virtual TSharedPtr GetPropertiesWidget() override; + + TSharedPtr>> GroupComboBox; + TArray> Selectable; + + + STimelineClip* TimelineClip; +};