diff --git a/Resources/Presets/PresetVideo/Lighting.mp4 b/Resources/Presets/PresetVideo/Lighting.mp4 new file mode 100644 index 0000000..9173ed8 Binary files /dev/null and b/Resources/Presets/PresetVideo/Lighting.mp4 differ diff --git a/Resources/Presets/亮白.dat b/Resources/Presets/亮白.dat new file mode 100644 index 0000000..cc06c75 Binary files /dev/null and b/Resources/Presets/亮白.dat differ diff --git a/Resources/Presets/橘色.dat b/Resources/Presets/橘色.dat new file mode 100644 index 0000000..73e3c4e Binary files /dev/null and b/Resources/Presets/橘色.dat differ diff --git a/Resources/Presets/紫色.dat b/Resources/Presets/紫色.dat new file mode 100644 index 0000000..81f0004 Binary files /dev/null and b/Resources/Presets/紫色.dat differ diff --git a/Resources/Presets/红-暗.dat b/Resources/Presets/红-暗.dat new file mode 100644 index 0000000..595c967 Binary files /dev/null and b/Resources/Presets/红-暗.dat differ diff --git a/Resources/Presets/红色.dat b/Resources/Presets/红色.dat new file mode 100644 index 0000000..b1bdfd0 Binary files /dev/null and b/Resources/Presets/红色.dat differ diff --git a/Resources/Presets/绿色.dat b/Resources/Presets/绿色.dat new file mode 100644 index 0000000..e7f09d6 Binary files /dev/null and b/Resources/Presets/绿色.dat differ diff --git a/Resources/Presets/蓝色.dat b/Resources/Presets/蓝色.dat new file mode 100644 index 0000000..b4d09e8 Binary files /dev/null and b/Resources/Presets/蓝色.dat differ diff --git a/Resources/Presets/闪电.dat b/Resources/Presets/闪电.dat new file mode 100644 index 0000000..a6aabf9 Binary files /dev/null and b/Resources/Presets/闪电.dat differ diff --git a/Resources/Presets/青柠.dat b/Resources/Presets/青柠.dat new file mode 100644 index 0000000..48d5bf6 Binary files /dev/null and b/Resources/Presets/青柠.dat differ diff --git a/Source/Cut5/Utils/Utils.cpp b/Source/Cut5/Utils/Utils.cpp index b8ece19..2a02661 100644 --- a/Source/Cut5/Utils/Utils.cpp +++ b/Source/Cut5/Utils/Utils.cpp @@ -127,16 +127,16 @@ void FUtils::TrackEncodeVideo(const FTrackData& TrackData, const FString& Export FString OutputFile = FPaths::ConvertRelativePathToFull((FPaths::Combine(FPaths::ProjectDir(), TEXT("output.mp4")))); int32 StartFrame = (TempClipData.VideoStartFrame) % static_cast(FGlobalData::GlobalFPS);; int32 EndFrame = (TempClipData.VideoEndFrame) % static_cast(FGlobalData::GlobalFPS); - - GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("StartFrame: %d, EndFrame: %d"), StartFrame, EndFrame)); - //输出文件名字 - GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("OutputFile: %s"), *OutputFile)); - //输入文件名字 - GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("InputFile: %s"), *InputFile)); - //开始时间 - GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("StartTime: %s"), *StartTime)); - //结束时间 - GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("EndTime: %s"), *EndTime)); + // + // GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("StartFrame: %d, EndFrame: %d"), StartFrame, EndFrame)); + // //输出文件名字 + // GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("OutputFile: %s"), *OutputFile)); + // //输入文件名字 + // GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("InputFile: %s"), *InputFile)); + // //开始时间 + // GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("StartTime: %s"), *StartTime)); + // //结束时间 + // GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("EndTime: %s"), *EndTime)); // 构造FFmpeg命令 FString Command = FString::Printf(TEXT("-y -i %s -ss %s -to %s -c copy %s"), *InputFile, *StartTime, *EndTime, *OutputFile); diff --git a/Source/Cut5/Widgets/Commands/TimelineTrackCommands.cpp b/Source/Cut5/Widgets/Commands/TimelineTrackCommands.cpp new file mode 100644 index 0000000..f476bf0 --- /dev/null +++ b/Source/Cut5/Widgets/Commands/TimelineTrackCommands.cpp @@ -0,0 +1,8 @@ +#include "TimelineTrackCommands.h" + +#define LOCTEXT_NAMESPACE "FTimelineClipCommands" +void FTimelineTrackCommands::RegisterCommands() +{ + UI_COMMAND(Remove, "移除", "Executes My TimelineClipCommands", EUserInterfaceActionType::Button, FInputChord()); +} +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Source/Cut5/Widgets/Commands/TimelineTrackCommands.h b/Source/Cut5/Widgets/Commands/TimelineTrackCommands.h new file mode 100644 index 0000000..a97370f --- /dev/null +++ b/Source/Cut5/Widgets/Commands/TimelineTrackCommands.h @@ -0,0 +1,22 @@ + + +#pragma once +#include "CoreMinimal.h" +#include "Framework/Commands/Commands.h" + +class FTimelineTrackCommands : public TCommands +{ +public: + + FTimelineTrackCommands() + : TCommands(TEXT("FTimelineTrackCommands"), NSLOCTEXT("Contexts", "FTimelineClipCommands", "FTimelineClipCommands"), NAME_None, FAppStyle::GetAppStyleSetName()) + { + // 这里可以设置你的命令的默认键盘快捷键 + } + + // TCommands<> 接口 + virtual void RegisterCommands() override; + + TSharedPtr Remove; + +}; \ No newline at end of file diff --git a/Source/Cut5/Widgets/DefineGlobal.h b/Source/Cut5/Widgets/DefineGlobal.h index 1901f65..bbfde2f 100644 --- a/Source/Cut5/Widgets/DefineGlobal.h +++ b/Source/Cut5/Widgets/DefineGlobal.h @@ -271,7 +271,7 @@ struct CUT5_API FClipData // Cursor TArray Cursors; - EPresetType PresetType; + EPresetType PresetType = EPresetType::NotAPresets; }; struct CUT5_API FTimelinePropertyData { diff --git a/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp b/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp index adf34a6..6cdc9b4 100644 --- a/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp +++ b/Source/Cut5/Widgets/DragDropOperator/DragDropOperator.cpp @@ -76,9 +76,34 @@ void DragDropOperator::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& NewClipData.ClipType = TrackHead->TrackData.TrackType; NewClipData.ClipStartFrame = MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X / FGlobalData::DefaultTimeTickSpace; NewClipData.ClipEndFrame = (MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X + 100) / FGlobalData::DefaultTimeTickSpace; - NewClipData.ClipColors.Add(FLinearColor(1, 1, 1, 1)); - NewClipData.Cursors.Add(FCursorData(0, FLinearColor(1, 0, 0, 1))); - NewClipData.Cursors.Add(FCursorData(5, FLinearColor(0, 1, 1, 1))); + if (PresetDragOperation->PresetData.PresetType == EPresetType::Color) + { + NewClipData.ClipColors.Add(PresetDragOperation->PresetData.Colors[0]); + } + else + { + NewClipData.ClipColors.Add(FLinearColor(0, 0, 0, 0)); + } + + + if (PresetDragOperation->PresetData.PresetType == EPresetType::Gradient) + { + if (PresetDragOperation->PresetData.Colors.Num() > 0) + { + for (int32 i = 0; i < PresetDragOperation->PresetData.Colors.Num(); i++) + { + NewClipData.Cursors.Add(FCursorData(i * (100 / FGlobalData::DefaultTimeTickSpace / PresetDragOperation->PresetData.Colors.Num()), PresetDragOperation->PresetData.Colors[i])); + } + } + else + { + NewClipData.Cursors.Add(FCursorData(0, FLinearColor(1, 0, 0, 1))); + NewClipData.Cursors.Add(FCursorData(6, FLinearColor(0, 1, 1, 1))); + } + } + + + TrackHead->TrackData.ClipData.Add(NewClipData); TrackBody->CallRender(); return; diff --git a/Source/Cut5/Widgets/Presets/SClipCursor.cpp b/Source/Cut5/Widgets/Presets/SClipCursor.cpp index 94e3e22..3e8dcad 100644 --- a/Source/Cut5/Widgets/Presets/SClipCursor.cpp +++ b/Source/Cut5/Widgets/Presets/SClipCursor.cpp @@ -4,6 +4,7 @@ #include "SClipCursor.h" #include "SlateOptMacros.h" +// #include "AppFramework/Public/Widgets/Colors/SColorPicker.h" #include "Cut5/Utils/Utils.h" #include "Cut5/Widgets/STimelineClip.h" @@ -41,4 +42,19 @@ void SClipCursor::Tick(const FGeometry& AllottedGeometry, const double InCurrent SetRenderTransform(FSlateRenderTransform(FVector2D(CursorData->CursorFrameOffset * FGlobalData::DefaultTimeTickSpace - 11, 0))); } +FReply SClipCursor::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) +{ + if (MouseEvent.IsMouseButtonDown(EKeys::RightMouseButton)) + { + // GEngine->GameViewport->AddViewportWidgetContent( SNew(SColorPicker) + // .OnColorCommitted_Lambda([this](FLinearColor Color, ETextCommit::Type CommitType) + // { + // CursorData->Color = Color; + // }), 99); + + + } + return FReply::Handled(); +} + END_SLATE_FUNCTION_BUILD_OPTIMIZATION diff --git a/Source/Cut5/Widgets/Presets/SClipCursor.h b/Source/Cut5/Widgets/Presets/SClipCursor.h index 573ff34..9a2c6f8 100644 --- a/Source/Cut5/Widgets/Presets/SClipCursor.h +++ b/Source/Cut5/Widgets/Presets/SClipCursor.h @@ -26,5 +26,5 @@ public: FCursorData* CursorData; FClipData* ClipData; class STimelineClip* TimelineClip; - + virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; }; diff --git a/Source/Cut5/Widgets/Presets/SEffectPreset.cpp b/Source/Cut5/Widgets/Presets/SEffectPreset.cpp index 83d7041..fa7a26d 100644 --- a/Source/Cut5/Widgets/Presets/SEffectPreset.cpp +++ b/Source/Cut5/Widgets/Presets/SEffectPreset.cpp @@ -4,6 +4,7 @@ #include "SEffectPreset.h" #include "SlateOptMacros.h" +#include "Cut5/Utils/Utils.h" #include "Widgets/Input/SComboBox.h" BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION @@ -15,6 +16,19 @@ void SEffectPreset::Construct(const FArguments& InArgs) PresetType = InArgs._PresetType; MainInterface = InArgs._MainInterface; + + + if (!PresetPath.IsEmpty()) + { + TArray Data; + FString LoadPath = FUtils::GetResourcesPath(TEXT("Presets/") + PresetPath, true); + // GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Cyan, LoadPath); + FFileHelper::LoadFileToArray(Data, *LoadPath); + + FMemoryReader MemoryReader(Data); + MemoryReader << PresetsData; + } + PresetsData.PresetType = PresetType; ChildSlot [ @@ -35,7 +49,7 @@ void SEffectPreset::Construct(const FArguments& InArgs) .OnClicked_Lambda([this]() { MainInterface->UpdateProperties(this); - GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Cyan, TEXT("Clicked")); + // GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Cyan, TEXT("Clicked")); return FReply::Handled().DetectDrag(SharedThis(this), EKeys::LeftMouseButton); }) ] diff --git a/Source/Cut5/Widgets/SCustomInputPanel.cpp b/Source/Cut5/Widgets/SCustomInputPanel.cpp index 58a91a8..b2d1799 100644 --- a/Source/Cut5/Widgets/SCustomInputPanel.cpp +++ b/Source/Cut5/Widgets/SCustomInputPanel.cpp @@ -352,15 +352,15 @@ void SCustomInputPanel::Construct(const FArguments& InArgs) AddPreset(TEXT("结束后常亮"), TEXT(""), EPresetType::Color); AddPreset(TEXT("渐变"), TEXT(""), EPresetType::Gradient); - AddPreset(TEXT("亮白"), TEXT(""), EPresetType::Color); - AddPreset(TEXT("红色"), TEXT(""), EPresetType::Color); - AddPreset(TEXT("紫色"), TEXT(""), EPresetType::Color); - AddPreset(TEXT("蓝色"), TEXT(""), EPresetType::Color); - AddPreset(TEXT("绿色"), TEXT(""), EPresetType::Color); - AddPreset(TEXT("橘色"), TEXT(""), EPresetType::Color); - AddPreset(TEXT("青柠"), TEXT(""), EPresetType::Color); - AddPreset(TEXT("红-暗"), TEXT(""), EPresetType::Gradient); - AddPreset(TEXT("闪电"), TEXT(""), EPresetType::Video); + AddPreset(TEXT("亮白"), TEXT("亮白.dat"), EPresetType::Color); + AddPreset(TEXT("红色"), TEXT("红色.dat"), EPresetType::Color); + AddPreset(TEXT("紫色"), TEXT("紫色.dat"), EPresetType::Color); + AddPreset(TEXT("蓝色"), TEXT("蓝色.dat"), EPresetType::Color); + AddPreset(TEXT("绿色"), TEXT("绿色.dat"), EPresetType::Color); + AddPreset(TEXT("橘色"), TEXT("橘色.dat"), EPresetType::Color); + AddPreset(TEXT("青柠"), TEXT("青柠.dat"), EPresetType::Color); + AddPreset(TEXT("红-暗"), TEXT("红-暗.dat"), EPresetType::Gradient); + AddPreset(TEXT("闪电"), TEXT("闪电.dat"), EPresetType::Video); AddPreset(TEXT("跑马灯-玫红"), TEXT("")); AddPreset(TEXT("心跳-宏"), TEXT("")); AddPreset(TEXT("5次闪电"), TEXT("")); diff --git a/Source/Cut5/Widgets/SCutTimeline.cpp b/Source/Cut5/Widgets/SCutTimeline.cpp index 12b5dfd..458cad2 100644 --- a/Source/Cut5/Widgets/SCutTimeline.cpp +++ b/Source/Cut5/Widgets/SCutTimeline.cpp @@ -323,7 +323,7 @@ void SCutTimeline::Construct(const FArguments& InArgs) // FTrackData LightBarData(TEXT("灯带"), ETrackType::LightBarTrack); // AddNewTrackToGroup(TEXT("固定轨道"), LightBarData); // FTrackData LightBarData2(TEXT("灯带2"), ETrackType::LightBarTrack); - // AddNewTrackToGroup(TEXT("固定轨道"), LightBarData); + // AddNewTrackToGroup(TEXT("固定轨道"), LightBarData2); // FTrackData SpotLightData(TEXT("聚光灯"), ETrackType::SpotLightTrack); // AddNewTrackToGroup(TEXT("固定轨道"), SpotLightData); } diff --git a/Source/Cut5/Widgets/STimelineClip.cpp b/Source/Cut5/Widgets/STimelineClip.cpp index 921746d..20d24ff 100644 --- a/Source/Cut5/Widgets/STimelineClip.cpp +++ b/Source/Cut5/Widgets/STimelineClip.cpp @@ -126,8 +126,8 @@ void STimelineClip::Construct(const FArguments& InArgs) .VAlign(VAlign_Fill) [ SNew(SBorder) - .ColorAndOpacity(ClipData->ClipColors[0]) - .BorderBackgroundColor(ClipData->ClipColors[0]) + // .ColorAndOpacity(ClipData->ClipColors[0]) + // .BorderBackgroundColor(ClipData->ClipColors[0]) .OnMouseButtonDown(this, &STimelineClip::OnBorderMouseButtonDown) .OnMouseButtonUp(this, &STimelineClip::OnBorderMouseButtonUp) ] @@ -155,6 +155,7 @@ void STimelineClip::Construct(const FArguments& InArgs) NewClipCursor.ToSharedRef() ]; } + } } @@ -175,6 +176,10 @@ void STimelineClip::Seek(int32 Frame) } case ETrackType::VideoTrack: { + if (ClipData->PresetType != EPresetType::NotAPresets) + { + break; + } if (!ClipData->VideoCapture || Frame > ClipData->ClipEndFrame || Frame < 0) { return; @@ -288,11 +293,46 @@ void STimelineClip::Seek(int32 Frame) } } + break; } case ETrackType::LightArrayTrack: { const int32 Offset = Frame - ClipData->ClipStartFrame; const int32 SeekMovieFrame = ClipData->VideoStartFrame + Offset; + + if (ClipData->PresetType == EPresetType::Color) + { + + TArray Colors; + Colors.Init(ClipData->ClipColors[0].ToFColor(false), FGlobalData::LightArrayX * FGlobalData::LightArrayY * 4); + MainWidgetInterface->OnUpdateLightArray(Colors); + break; + } + else if (ClipData->PresetType == EPresetType::Gradient) + { + int32 Between = -1; + for (int32 i = 0; i < ClipData->Cursors.Num() - 1; i++) + { + if (SeekMovieFrame >= ClipData->Cursors[i].CursorFrameOffset && SeekMovieFrame <= ClipData->Cursors[i + 1].CursorFrameOffset) + { + Between = i; + } + } + if (Between != -1) + { + TArray Colors; + Colors.Init(FLinearColor::Black.ToFColor(false), FGlobalData::LightArrayX * FGlobalData::LightArrayY * 4); + for (int32 i = 0; i < FGlobalData::LightArrayX * FGlobalData::LightArrayY; i++) + { + Colors[i] = FMath::Lerp(ClipData->Cursors[Between].Color, ClipData->Cursors[Between + 1].Color, (float)(SeekMovieFrame - ClipData->Cursors[Between].CursorFrameOffset) / (float)(ClipData->Cursors[Between + 1].CursorFrameOffset - ClipData->Cursors[Between].CursorFrameOffset)).ToFColor(false); + } + MainWidgetInterface->OnUpdateLightArray(Colors); + } + + break; + } + + if (SeekMovieFrame < ClipData->LightArrayData.Num()) { MainWidgetInterface->OnUpdateLightArray(ClipData->LightArrayData[SeekMovieFrame]); @@ -462,6 +502,7 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe TArray GradientStops; for (int32 i = 0; i < ClipData->Cursors.Num(); i++) { + // GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("CursorFrameOffset %s"), *ClipData->Cursors[i].Color.ToString())); GradientStops.Add(FSlateGradientStop(FVector2D(ClipData->Cursors[i].CursorFrameOffset * FGlobalData::DefaultTimeTickSpace, 0), ClipData->Cursors[i].Color)); } @@ -471,8 +512,10 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe } - return SCompoundWidget::OnPaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, - bParentEnabled); + + return SCompoundWidget::OnPaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId + 1, InWidgetStyle, + bParentEnabled); + } FReply STimelineClip::OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) diff --git a/Source/Cut5/Widgets/STrackBody.cpp b/Source/Cut5/Widgets/STrackBody.cpp index 3b42967..cbd85c5 100644 --- a/Source/Cut5/Widgets/STrackBody.cpp +++ b/Source/Cut5/Widgets/STrackBody.cpp @@ -165,11 +165,12 @@ void STrackBody::Seek(int32 Frame) void STrackBody::DeleteUseLessClips() { - for (int32 i = 0; i < TrackHead->TrackData.ClipData.Num(); i++) + for (int32 i = TrackHead->TrackData.ClipData.Num() - 1; i >= 0; i--) { - if (!TrackHead->TrackData.ClipData[i].ResourcePropertyDataPtr->bIsValid) + if (TrackHead->TrackData.ClipData[i].ResourcePropertyDataPtr->bIsValid == false) { - + TrackHead->TrackData.ClipData.RemoveAt(i); + CallRender(); } } } diff --git a/Source/Cut5/Widgets/STrackHead.cpp b/Source/Cut5/Widgets/STrackHead.cpp index 0cb5da4..27f5bc8 100644 --- a/Source/Cut5/Widgets/STrackHead.cpp +++ b/Source/Cut5/Widgets/STrackHead.cpp @@ -4,6 +4,8 @@ #include "STrackHead.h" #include "SlateOptMacros.h" +#include "Commands/TimelineTrackCommands.h" +#include "MicroWidgets/STips.h" BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION @@ -13,6 +15,18 @@ void STrackHead::Construct(const FArguments& InArgs) CutTimeline = InArgs._CutTimeline; MainWidgetInterface = InArgs._MainWidgetInterface; GroupName = InArgs._GroupName; + + FTimelineTrackCommands::Register(); + CommandList = MakeShared(); + + CommandList->MapAction(FTimelineTrackCommands::Get().Remove, FExecuteAction::CreateLambda([this]() + { + GEngine->GameViewport->AddViewportWidgetContent(SNew(STips).Title(TEXT("是否删除轨道")).SubTitle(TEXT("删除轨道后,轨道上的所有片段都会被删除,是否继续?")).OnEnsure_Lambda([this](const FString& String) + { + CutTimeline->RemoveTrack(TrackData.Guid); + })); + + })); TSharedPtr Image = SNew(SImage); ChildSlot [ @@ -89,7 +103,13 @@ void STrackHead::Construct(const FArguments& InArgs) FReply STrackHead::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) { - // CutTimeline->RemoveTrack(TrackData.Guid); + if (MouseEvent.IsMouseButtonDown(EKeys::RightMouseButton)) + { + FMenuBuilder MenuBuilder(true, CommandList); + MenuBuilder.AddMenuEntry(FTimelineTrackCommands::Get().Remove); + FSlateApplication::Get().PushMenu(AsShared(), FWidgetPath(), MenuBuilder.MakeWidget(), FSlateApplication::Get().GetCursorPos(), FPopupTransitionEffect(FPopupTransitionEffect::ContextMenu)); + } + // return FReply::Unhandled(); } diff --git a/Source/Cut5/Widgets/STrackHead.h b/Source/Cut5/Widgets/STrackHead.h index e22a377..165d06f 100644 --- a/Source/Cut5/Widgets/STrackHead.h +++ b/Source/Cut5/Widgets/STrackHead.h @@ -30,4 +30,6 @@ public: ICutMainWidgetInterface* MainWidgetInterface; FString GroupName; virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; + + TSharedPtr CommandList; };