diff --git a/Cut5.sln.DotSettings.user b/Cut5.sln.DotSettings.user
index 82c3d3d..8c35d97 100644
--- a/Cut5.sln.DotSettings.user
+++ b/Cut5.sln.DotSettings.user
@@ -1,2 +1,3 @@
+ SUGGESTION
True
\ No newline at end of file
diff --git a/Source/Cut5/Interface/SoundInterface.cpp b/Source/Cut5/Interface/SoundInterface.cpp
index 4e262a4..c81454b 100644
--- a/Source/Cut5/Interface/SoundInterface.cpp
+++ b/Source/Cut5/Interface/SoundInterface.cpp
@@ -44,7 +44,7 @@ uint32 FSoundThread::Run()
{
const int32 Offset = SeekedFrame * (SampleRate / FGlobalData::GlobalFPS) * ByteNum * 2;
const int32 Size = SampleRate / FGlobalData::GlobalFPS;
- if (Audio.Num() < Offset + Size)
+ if (Audio.Num() < Offset + Size * ByteNum)
{
SeekedFrame = 0;
continue;
diff --git a/Source/Cut5/Utils/Utils.cpp b/Source/Cut5/Utils/Utils.cpp
index ab2c2c1..88b747c 100644
--- a/Source/Cut5/Utils/Utils.cpp
+++ b/Source/Cut5/Utils/Utils.cpp
@@ -589,8 +589,8 @@ TArray FUtils::ExportPsaf(FTrackData TrackData, const FString&
-
- FString psafPath = ExportPath + ExportName + FString::FromInt(i) + ".psaf";
+
+ FString psafPath = ExportPath + FString::FromInt(i) + ".psaf";
FString psafPath2 = leftStr + ".psaf2";
diff --git a/Source/Cut5/Widgets/Curtain/SCurtain.cpp b/Source/Cut5/Widgets/Curtain/SCurtain.cpp
index 98bf1d0..f7a5544 100644
--- a/Source/Cut5/Widgets/Curtain/SCurtain.cpp
+++ b/Source/Cut5/Widgets/Curtain/SCurtain.cpp
@@ -47,7 +47,27 @@ void SCurtain::Construct(const FArguments& InArgs)
.ButtonStyle(FCutButtonStyle::Get(), Curtain->bIsActive ? "Curtain.CurtainButtonSelected" : "Curtain.CurtainButton")
.OnClicked_Lambda([this]()
{
- TSharedPtr CurtainDragDrop = OpenThis();
+ TSharedPtr CurtainDragDrop;
+ if (!Curtain->bIsActive)
+ {
+ CurtainDragDrop = OpenThis();
+ InlineEditableTextBlock->EnterEditingMode();
+ }
+ else
+ {
+ InlineEditableTextBlock->EnterEditingMode();
+ }
+
+ if (CurtainDragDrop == nullptr)
+ {
+ CurtainDragDrop = MakeShared();
+ CurtainDragDrop->CurtainIndex = CurtainIndex;
+ CurtainDragDrop->GroupIndex = CurtainGroup - &CurtainPanel->Groups[0];
+ CurtainDragDrop->DragDropType = FCutDragDropBase::EType::CurtainDrag;
+ CurtainDragDrop->DraggingWidget = SharedThis(this);
+
+ }
+
return FReply::Handled().DetectDrag(SharedThis(this), EKeys::LeftMouseButton).BeginDragDrop(CurtainDragDrop.ToSharedRef());
})
]
@@ -66,6 +86,13 @@ void SCurtain::Construct(const FArguments& InArgs)
+ SHorizontalBox::Slot()
[
SAssignNew(InlineEditableTextBlock, SInlineEditableTextBlock)
+ .OnEnterEditingMode_Lambda([this]()
+ {
+ if (!Curtain->bIsActive)
+ {
+ OpenThis();
+ }
+ })
.Text(FText::FromString(Curtain->CurtainName))
.Font(TitleText.Font)
.OnTextCommitted_Lambda([this](const FText& Text, ETextCommit::Type CommitType)
@@ -114,10 +141,11 @@ FReply SCurtain::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEv
CurtainPanel->ShowCurtainCommand(Curtain->CurtainUUID);
return FReply::Handled();
}
- if (!Curtain->bIsActive)
- {
- OpenThis();
- }
+ InlineEditableTextBlock->EnterEditingMode();
+ // if (!Curtain->bIsActive)
+ // {
+ // OpenThis();
+ // }
return SCompoundWidget::OnMouseButtonDown(MyGeometry, MouseEvent);
}
diff --git a/Source/Cut5/Widgets/FX/SEffectCardGroup.cpp b/Source/Cut5/Widgets/FX/SEffectCardGroup.cpp
index 5212bd7..0149293 100644
--- a/Source/Cut5/Widgets/FX/SEffectCardGroup.cpp
+++ b/Source/Cut5/Widgets/FX/SEffectCardGroup.cpp
@@ -418,9 +418,7 @@ void SEffectCardGroup::CallRender()
.VAlign(VAlign_Fill)
.OnClicked_Lambda([this]()
{
- // 新建卡牌后 对卡牌进行个体保存。
- FEffectCardProperty NewCard;
- NewCard.Name = TEXT("未命名") + NewCard.Guid.ToString();
+
@@ -437,6 +435,10 @@ void SEffectCardGroup::CallRender()
}
ID++;
}
+
+ // 新建卡牌后 对卡牌进行个体保存。
+ FEffectCardProperty NewCard;
+ NewCard.Name = TEXT("未命名") + FString::FromInt(ID);
NewCard.ID = ID;
diff --git a/Source/Cut5/Widgets/MicroWidgets/SNewProjectTips.cpp b/Source/Cut5/Widgets/MicroWidgets/SNewProjectTips.cpp
index 831902a..31f56fb 100644
--- a/Source/Cut5/Widgets/MicroWidgets/SNewProjectTips.cpp
+++ b/Source/Cut5/Widgets/MicroWidgets/SNewProjectTips.cpp
@@ -11,6 +11,7 @@ BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SNewProjectTips::Construct(const FArguments& InArgs)
{
OnEnsure = InArgs._OnEnsure;
+ AlreadyExistsData = InArgs._AlreadyExistsData;
FTextBlockStyle NormalText = FAppStyle::GetWidgetStyle("NormalText");
NormalText.SetFontSize(20);
ChildSlot
@@ -58,6 +59,12 @@ void SNewProjectTips::Construct(const FArguments& InArgs)
ConfirmButton->SetEnabled(false);
return false;
}
+ if (AlreadyExistsData.Contains(InText.ToString()))
+ {
+ OutText = FText::FromString(TEXT("项目名称已存在"));
+ ConfirmButton->SetEnabled(false);
+ return false;
+ }
ConfirmButton->SetEnabled(true);
return true;
})
@@ -68,7 +75,7 @@ void SNewProjectTips::Construct(const FArguments& InArgs)
{
if (OnEnsure.ExecuteIfBound(InText.ToString()))
{
-
+
}
}
diff --git a/Source/Cut5/Widgets/MicroWidgets/SNewProjectTips.h b/Source/Cut5/Widgets/MicroWidgets/SNewProjectTips.h
index e818887..364feed 100644
--- a/Source/Cut5/Widgets/MicroWidgets/SNewProjectTips.h
+++ b/Source/Cut5/Widgets/MicroWidgets/SNewProjectTips.h
@@ -17,6 +17,7 @@ public:
{
}
SLATE_ARGUMENT(FString, Title)
+ SLATE_ARGUMENT(TArray, AlreadyExistsData)
SLATE_ARGUMENT(FString, SubTitle)
SLATE_EVENT(FOnEnsure, OnEnsure)
SLATE_END_ARGS()
@@ -26,5 +27,7 @@ public:
TSharedPtr EditableTextBox;
TSharedPtr ConfirmButton;
+
+ TArray AlreadyExistsData;
FOnEnsure OnEnsure;
};
diff --git a/Source/Cut5/Widgets/SCutMainWindow.cpp b/Source/Cut5/Widgets/SCutMainWindow.cpp
index bc8b3e8..d4809d3 100644
--- a/Source/Cut5/Widgets/SCutMainWindow.cpp
+++ b/Source/Cut5/Widgets/SCutMainWindow.cpp
@@ -121,6 +121,13 @@ void SCutMainWindow::Construct(const FArguments& InArgs)
]
]
+ SHorizontalBox::Slot()
+ .VAlign(VAlign_Center)
+ [
+ SNew(STextBlock)
+ .Text(FText::FromString(FString::Printf(TEXT("Ver. %s"), *FGlobalData::CutVersion)))
+ .Justification(ETextJustify::Center)
+ ]
+ + SHorizontalBox::Slot()
.SizeParam(FStretch(1.0))
[
SNew(SSpacer)
@@ -493,29 +500,43 @@ void SCutMainWindow::Construct(const FArguments& InArgs)
CutTimeline->CopyClipData.Empty();
TArray ClipBoardData;
FMemoryWriter Archive(ClipBoardData);
- int32 Count = CutTimeline->SelectedClips.Num();
- TArray SavedData;
+
+ // first nest is the number of track group instances
+ // second nest is the number of clips in each track group instance
+ // nest can be empty
+ TArray> SavedData;
+
+
+
+ int32 i = 0;
+ bool bHasData = false;
for (FSingleTrackGroupInstance& Instance : CutTimeline->TrackGroupInstances)
{
- TSharedPtr TrackBody = StaticCastSharedPtr(Instance.Body);
+ TArray TempSavedData;
+ const TSharedPtr TrackBody = StaticCastSharedPtr(Instance.Body);
for (FClipData& ClipData : TrackBody->TrackHead->TrackData.ClipData)
{
if (CutTimeline->SelectedClips.Contains(ClipData.ClipGuid))
{
- SavedData.Add(ClipData);
- break;
+ bHasData = true;
+ TempSavedData.Add(ClipData);
+ continue;
}
-
+ }
+ if (bHasData)
+ {
+ i++;
+ SavedData.Add(TempSavedData);
}
}
Archive << SavedData;
-
- FString Base = FBase64::Encode(ClipBoardData);
+
+ const FString Base = FBase64::Encode(ClipBoardData);
FPlatformApplicationMisc::ClipboardCopy(*Base);
}));
CommandList->MapAction(FShortCutCommands::Get().Paste, FExecuteAction::CreateLambda([this]()
{
-
+ UpdateProperties(nullptr);
FString ClipBoardString;
FPlatformApplicationMisc::ClipboardPaste(ClipBoardString);
TArray Dest;
@@ -524,27 +545,64 @@ void SCutMainWindow::Construct(const FArguments& InArgs)
FMemoryReader Reader(Dest);
- TArray CopyClipData;
+ TArray> CopyClipData;
Reader << CopyClipData;
- // for (FClipData& ClipData : CopyClipData)
- // {
- // for (FSingleTrackGroupInstance& Instance : CutTimeline->TrackGroupInstances)
- // {
- // TSharedPtr TrackBody = StaticCastSharedPtr(Instance.Body);
- // FVector2D Pos = TrackBody->GetCachedGeometry().AbsoluteToLocal(NewMouseEvent.GetScreenSpacePosition());
- // if (TrackBody->TrackHead->TrackData.DeviceTrack.Guid == ClipData.BindTrackGuid)
- // {
- // FClipData NewClipData = ClipData;
- // NewClipData.ClipGuid = FGuid::NewGuid();
- // int32 Length = NewClipData.ClipEndFrame - NewClipData.ClipStartFrame;
- // NewClipData.ClipStartFrame = FMath::RoundToInt(Pos.X / FGlobalData::DefaultTimeTickSpace);
- // NewClipData.ClipEndFrame = NewClipData.ClipStartFrame + Length;
- // DragDropOperator::GetDragDropOperator()->UpdateClipProcess(this, NewClipData);
- // TrackBody->TrackHead->TrackData.ClipData.Add(NewClipData);
- // TrackBody->CallRender();
- // }
- // }
- // }
+
+ // 先计算出最靠左侧的片段
+ int32 MostLeftFrame = INT_MAX;
+ for (TArray& ClipDataArray : CopyClipData)
+ {
+ for (const FClipData& ClipData : ClipDataArray)
+ {
+ MostLeftFrame = FMath::Min(MostLeftFrame, ClipData.ClipStartFrame);
+ }
+ }
+
+
+ int32 CurrentIndex = 0;
+ TSharedPtr BeginBody = CutTimeline->GetCurrentCursorUsingBody();
+ for (TArray& ClipDataArray : CopyClipData)
+ {
+ if (ClipDataArray.Num() == 0)
+ {
+ BeginBody = CutTimeline->IterateTrackBody(BeginBody);
+ CurrentIndex++;
+ continue;
+ }
+ if (BeginBody == nullptr)
+ {
+ // IterateTrackBody will return nullptr if the track body is the last one
+ break;
+ }
+
+
+ for (FClipData& ClipData : ClipDataArray)
+ {
+ if (FUtils::DetectDragTypeCanDrop(ClipData, BeginBody->TrackHead->TrackData.TrackType))
+ {
+ FVector2D Pos = BeginBody->GetCachedGeometry().AbsoluteToLocal(NewMouseEvent.GetScreenSpacePosition());
+ FClipData NewClipData = ClipData;
+ NewClipData.ClipGuid = FGuid::NewGuid();
+ NewClipData.BindTrackGuid = BeginBody->TrackHead->TrackData.DeviceTrack.Guid;
+
+ int32 Offset = NewClipData.ClipStartFrame - MostLeftFrame;
+
+ int32 Length = NewClipData.ClipEndFrame - NewClipData.ClipStartFrame;
+ NewClipData.ClipStartFrame = FMath::RoundToInt(Pos.X / FGlobalData::DefaultTimeTickSpace) + Offset;
+ NewClipData.ClipEndFrame = NewClipData.ClipStartFrame + Length;
+
+
+
+
+ BeginBody->TrackHead->TrackData.ClipData.Add(NewClipData);
+ DragDropOperator::GetDragDropOperator()->UpdateClipProcess(this, NewClipData);
+ }
+ }
+
+ BeginBody->CallRender();
+ BeginBody = CutTimeline->IterateTrackBody(BeginBody);
+ CurrentIndex++;
+ }
}));
FMainMenuCommands::Register();
@@ -993,9 +1051,11 @@ void SCutMainWindow::ExportProject(const FString& ExportPath)
FGlobalData::ExportPath = ExportPath / FGlobalData::CurrentProjectName + TEXT("_XML");
FPlatformFileManager::Get().GetPlatformFile().DeleteDirectoryRecursively(*FGlobalData::ExportPath);
+
IDList.Empty();
FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*FGlobalData::ExportPath);
+ FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(TEXT("C://temp"));
FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*(FGlobalData::ExportPath / "Video"));
FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*(FGlobalData::ExportPath / "Sound"));
FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*(FGlobalData::ExportPath / "PSAF"));
@@ -1151,7 +1211,7 @@ void SCutMainWindow::ExportProject(const FString& ExportPath)
}
Card->InsertNewChildElement("Step")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(ToStepID)));
- Card->InsertNewChildElement("SpecialEffectID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].Cards[j].ID)));
+ Card->InsertNewChildElement("SpecialEffectID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].Cards[j].ID - 1)));
Card->InsertNewChildElement("SerialNumberList")->InsertNewChildElement("SerialNumber")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].Cards[j].ID)));
}
}
@@ -1261,10 +1321,7 @@ void SCutMainWindow::ImportProject(const FString& ImportPath)
void SCutMainWindow::NewProject(const FString& NewPath)
{
- FUtils::AddTips(SNew(STips).Title(TEXT("警告")).SubTitle(TEXT("目录不为空!")).OnEnsure_Lambda([](const FString& String)
- {
-
- }));
+
FGlobalData::BasePath = NewPath;
CutTimeline->TimelineInfo.CurrentOpenFullPath = FUtils::MainSaveFullPath();
@@ -1332,15 +1389,43 @@ bool SCutMainWindow::PreNewProject()
IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
DesktopPlatform->OpenDirectoryDialog(nullptr, TEXT("选择新建路径"), String, String);
if (String.IsEmpty())
+ {
return false;
- FGlobalData::BasePath = String;
+ }
+
+ // 检测目录是否为空
+
+
+
+
+
+
+ class FDirectoryVisitor : public IPlatformFile::FDirectoryVisitor
+ {
+ virtual bool Visit(const TCHAR* FilenameOrDirectory, bool bIsDirectory) override
+ {
+ if (bIsDirectory)
+ {
+ Directories.Add(FilenameOrDirectory);
+ }
+ return true;
+ };
+ public:
+ TArray Directories;
+ };
+ FDirectoryVisitor Visitor;
+ FPlatformFileManager::Get().GetPlatformFile().IterateDirectory(*String, Visitor);
+
TSharedPtr NewProjectTips =
SNew(SNewProjectTips)
+ .AlreadyExistsData(Visitor.Directories)
.Title(TEXT("新建项目名字"));
- NewProjectTips->OnEnsure.BindLambda([this, NewProjectTips](FString String)
+
+ NewProjectTips->OnEnsure.BindLambda([this, NewProjectTips, String](FString EnsureString)
{
- FGlobalData::CurrentProjectName = String;
+ FGlobalData::BasePath = String;
+ FGlobalData::CurrentProjectName = EnsureString;
GEngine->GameViewport->RemoveViewportWidgetContent(NewProjectTips.ToSharedRef());
});
GEngine->GameViewport->AddViewportWidgetContent(
@@ -1864,8 +1949,21 @@ tinyxml2::XMLElement* SCutMainWindow::GetVideoElement(tinyxml2::XMLElement* Pare
VolumeEventValue->InsertNewText("100");
}
}
+ Index++;
+ }
+
+
+ if (Index == 0)
+ {
+ tinyxml2::XMLElement* VolumeEvent = VolumeEventList->InsertNewChildElement("VolumeEvent");
+ {
+ tinyxml2::XMLElement* VolumeEventTimeCode = VolumeEvent->InsertNewChildElement("TimeCode");
+ tinyxml2::XMLElement* VolumeEventValue = VolumeEvent->InsertNewChildElement("Value");
+
+ VolumeEventTimeCode->InsertNewText("0");
+ VolumeEventValue->InsertNewText("100");
+ }
}
- Index++;
}
else
{
@@ -2066,6 +2164,18 @@ tinyxml2::XMLElement* SCutMainWindow::GetSoundElement(tinyxml2::XMLElement* Pare
Index++;
}
+
+ if (Index == 0)
+ {
+ tinyxml2::XMLElement* VolumeEvent = VolumeEventList->InsertNewChildElement("VolumeEvent");
+ {
+ tinyxml2::XMLElement* VolumeEventTimeCode = VolumeEvent->InsertNewChildElement("TimeCode");
+ tinyxml2::XMLElement* VolumeEventValue = VolumeEvent->InsertNewChildElement("Value");
+
+ VolumeEventTimeCode->InsertNewText("0");
+ VolumeEventValue->InsertNewText("100");
+ }
+ }
}
else
diff --git a/Source/Cut5/Widgets/SCutTimeline.cpp b/Source/Cut5/Widgets/SCutTimeline.cpp
index bbd4f4a..588885e 100644
--- a/Source/Cut5/Widgets/SCutTimeline.cpp
+++ b/Source/Cut5/Widgets/SCutTimeline.cpp
@@ -320,7 +320,7 @@ void SCutTimeline::Construct(const FArguments& InArgs)
[
// Track Body
SAssignNew(TrackBodyScrollBox, SScrollBox)
-
+ .AllowOverscroll(EAllowOverscroll::Yes)
.ScrollBarVisibility(EVisibility::Hidden)
.AnimateWheelScrolling(true)
.OnUserScrolled_Lambda([this](float ScrollValue)
@@ -841,6 +841,44 @@ TArray SCutTimeline::GetClipDataByType(ETrackType TrackType)
return ClipData;
}
+TSharedPtr SCutTimeline::GetCurrentCursorUsingBody()
+{
+ float Y = TrackBodyScrollBox->GetCachedGeometry().AbsoluteToLocal(FSlateApplication::Get().GetCursorPos()).Y + TrackBodyScrollBox->GetScrollOffset();
+ int32 i = 0;
+ for (FSingleTrackGroupInstance& TrackGroup : TrackGroupInstances)
+ {
+ float CurrentY = FGlobalData::DefaultTrackHeight * i;
+ TSharedPtr TrackBody = StaticCastSharedPtr(TrackGroup.Body);
+ if (Y >= CurrentY && Y <= CurrentY + TrackBody->GetCachedGeometry().GetLocalSize().Y)
+ {
+ return TrackBody;
+ }
+ i++;
+ }
+ return nullptr;
+}
+
+TSharedPtr SCutTimeline::IterateTrackBody(TSharedPtr CurrentBody)
+{
+ int32 i = 0;
+ for (FSingleTrackGroupInstance& TrackGroup : TrackGroupInstances)
+ {
+ if (TrackGroup.Body == CurrentBody)
+ {
+ if (i + 1 < TrackGroupInstances.Num())
+ {
+ return StaticCastSharedPtr(TrackGroupInstances[i + 1].Body);
+ }
+ else
+ {
+ return nullptr;
+ }
+ }
+ i++;
+ }
+ return nullptr;
+}
+
FReply SCutTimeline::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent)
{
diff --git a/Source/Cut5/Widgets/SCutTimeline.h b/Source/Cut5/Widgets/SCutTimeline.h
index ed4f947..538f695 100644
--- a/Source/Cut5/Widgets/SCutTimeline.h
+++ b/Source/Cut5/Widgets/SCutTimeline.h
@@ -107,6 +107,8 @@ public:
FTrackGroup* GetTrackGroupByName(FString GroupName);
FTrackData* GetTrackDataByType(ETrackType TrackType);
TArray GetClipDataByType(ETrackType TrackType);
+ TSharedPtr GetCurrentCursorUsingBody();
+ TSharedPtr IterateTrackBody(TSharedPtr CurrentBody);
ICutMainWidgetInterface* MainWidgetInterface;
diff --git a/Source/Cut5/Widgets/STimelineClip.cpp b/Source/Cut5/Widgets/STimelineClip.cpp
index 1e30b57..330ce88 100644
--- a/Source/Cut5/Widgets/STimelineClip.cpp
+++ b/Source/Cut5/Widgets/STimelineClip.cpp
@@ -320,6 +320,10 @@ void STimelineClip::Seek(int32 Frame)
{
MainWidgetInterface->OnUpdateProjector(0, false);
}
+ else
+ {
+ MainWidgetInterface->OnUpdateProjector(0, true);
+ }
break;
}
case ETrackType::VideoTrack:
@@ -668,11 +672,11 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe
}
if (ClipData->bIsCycle == true)
{
- FSlateDrawElement::MakeText(OutDrawElements, LayerId + 9, AllottedGeometry.ToPaintGeometry(), FText::FromString(TEXT("循环播放")), FAppStyle::Get().GetWidgetStyle("NormalText").Font, ESlateDrawEffect::None, FLinearColor::White);
+ FSlateDrawElement::MakeText(OutDrawElements, LayerId + 9, AllottedGeometry.ToPaintGeometry(), FText::FromString(TEXT("循环\n播放")), FAppStyle::Get().GetWidgetStyle("NormalText").Font, ESlateDrawEffect::None, FLinearColor::White);
}
if (ClipData->bIsVirtual == true)
{
- FSlateDrawElement::MakeText(OutDrawElements, LayerId + 9, AllottedGeometry.ToPaintGeometry(), FText::FromString(TEXT("虚拟轨道(不可编辑)")), FAppStyle::Get().GetWidgetStyle("NormalText").Font, ESlateDrawEffect::None, FLinearColor::White);
+ FSlateDrawElement::MakeText(OutDrawElements, LayerId + 9, AllottedGeometry.ToPaintGeometry(), FText::FromString(TEXT("虚拟轨道\n(不可编辑)")), FAppStyle::Get().GetWidgetStyle("NormalText").Font, ESlateDrawEffect::None, FLinearColor::White);
}