2024-01-25 11:21:15 +08:00

265 lines
6.6 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "SMixer.h"
#include "MultiBoxBuilder.h"
#include "SMixerTrack.h"
#include "SlateOptMacros.h"
#include "SListView.h"
#include "SMixerEffectList.h"
#include "SScrollBox.h"
#include "Singleton/MixerList.h"
#define LOCTEXT_NAMESPACE "SMixer"
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void FMixerSelector::AddTrack(FMixerTrack* MixerTrack)
{
if (SelectedTracks.Contains(MixerTrack))
return;
SelectedTracks.Add(MixerTrack);
OnMixerTrackSelected.Broadcast(MixerTrack);
}
bool FMixerSelector::RemoveTrack(FMixerTrack* MixerTrack)
{
if (!SelectedTracks.Contains(MixerTrack))
return false;
SelectedTracks.Remove(MixerTrack);
OnMixerTrackDeselected.Broadcast(MixerTrack);
return true;
}
void FMixerSelector::UnselectAll()
{
for (FMixerTrack* MixerTrack : SelectedTracks)
{
OnMixerTrackDeselected.Broadcast(MixerTrack);
}
SelectedTracks.Empty();
}
SMixer::~SMixer()
{
FMixerList& MixerList = FMixerList::Get();
MixerList.OnMixerTrackCreated.RemoveAll(this);
MixerList.OnMixerTrackRemoved.RemoveAll(this);
}
void SMixer::Construct(const FArguments& InArgs)
{
FMixerList& MixerList = FMixerList::Get();
MixerList.OnMixerTrackCreated.AddRaw(this, &SMixer::OnMixerTrackCreated);
MixerList.OnMixerTrackRemoved.AddRaw(this, &SMixer::OnMixerTrackRemoved);
Selector.OnMixerTrackSelected.AddRaw(this, &SMixer::OnMixerTrackSelected);
Selector.OnMixerTrackDeselected.AddRaw(this, &SMixer::OnMixerTrackDeselected);
ChildSlot
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.FillWidth(1.f)
[
SAssignNew(ListView, SScrollBox)
.AnimateWheelScrolling(true)
.Orientation(EOrientation::Orient_Horizontal)
.ScrollBarThickness(FVector2D(2))
]
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SBox)
.WidthOverride(200)
[
SAssignNew(EffectList, SMixerEffectList)
]
]
];
for (FMixerTrack* Mixer : MixerList)
{
OnMixerTrackCreated(Mixer);
}
}
FReply SMixer::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
if (MouseEvent.GetEffectingButton() == EKeys::RightMouseButton)
{
FMenuBuilder MenuBuilder(true, nullptr);
MenuBuilder.AddMenuEntry(
LOCTEXT("AddDummyMixerTrack", "创建傀儡轨道"),
LOCTEXT("AddDummyMixerTrack_Tooltip", "创建一个新的傀儡轨道"),
FSlateIcon(),
FUIAction(FExecuteAction::CreateLambda([this]()
{
FMixerList& MixerList = FMixerList::Get();
MixerList.CreateDummyTrack("Dummy");
}))
);
FSlateApplication::Get().PushMenu(SharedThis(this), FWidgetPath(), MenuBuilder.MakeWidget(), FSlateApplication::Get().GetCursorPos(), FPopupTransitionEffect::ContextMenu);
}
else if (MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
{
Selector.UnselectAll();
EffectList->SetMixerTrack(nullptr);
}
return FReply::Unhandled();
}
FReply SMixer::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent)
{
if (InKeyEvent.GetKey() == EKeys::LeftShift || InKeyEvent.GetKey() == EKeys::RightShift)
{
bShiftDown = true;
}
if (InKeyEvent.GetKey() == EKeys::Delete)
{
for (FMixerTrack* MixerTrack : Selector.GetSelectedTracks())
{
FMixerList::Get().RemoveTrack(MixerTrack);
}
Selector.UnselectAll();
}
return FReply::Unhandled();
}
FReply SMixer::OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent)
{
if (InKeyEvent.GetKey() == EKeys::LeftShift || InKeyEvent.GetKey() == EKeys::RightShift)
{
bShiftDown = false;
}
return FReply::Unhandled();
}
void SMixer::OnMixerTrackCreated(FMixerTrack* MixerTrack)
{
ListView->AddSlot()
[
SNew(SMixerTrack)
.MixerTrack(MixerTrack)
.OnClicked(this, &SMixer::OnMixerTrackClicked)
];
}
void SMixer::OnMixerTrackRemoved(FMixerTrack* MixerTrack)
{
if (Selector.RemoveTrack(MixerTrack))
{
Selector.AddTrack(FMixerList::Get().GetMaster());
}
ForeachMixerTrackWidget([&, this](TSharedRef<SMixerTrack> MixerTrackWidget)
{
if (MixerTrackWidget->GetMixerTrack() == MixerTrack)
{
ListView->RemoveSlot(MixerTrackWidget);
return false;
}
return true;
});
}
void SMixer::OnMixerTrackClicked(FMixerTrack* InMixerTrack)
{
Selector.UnselectAll();
if (bShiftDown)
{
const TArray<FMixerTrack*>& Selected = Selector.GetSelectedTracks();
if (Selected.Num() > 0)
{
const TSharedPtr<SScrollPanel> ScrollPanel = ListView->GetScrollPanel();
FChildren* Children = ScrollPanel->GetChildren();
for (int32 i = 0; i < Children->Num(); i++)
{
TSharedRef<SWidget> Child = Children->GetChildAt(i);
const TSharedRef<SMixerTrack> MixerTrackWidget = StaticCastSharedRef<SMixerTrack>(Child);
if (MixerTrackWidget->GetMixerTrack() == Selected[0])
{
int32 StartIndex = i;
for (int32 j = 0; j < Children->Num(); j++)
{
TSharedRef<SWidget> Child2 = Children->GetChildAt(j);
const TSharedRef<SMixerTrack> MixerTrackWidget2 = StaticCastSharedRef<SMixerTrack>(Child2);
if (MixerTrackWidget2->GetMixerTrack() == InMixerTrack)
{
int32 EndIndex = j;
if (StartIndex > EndIndex)
{
const int32 Temp = StartIndex;
StartIndex = EndIndex;
EndIndex = Temp;
}
for (int32 k = StartIndex; k <= EndIndex; k++)
{
TSharedRef<SWidget> Child3 = Children->GetChildAt(k);
const TSharedRef<SMixerTrack> MixerTrackWidget3 = StaticCastSharedRef<SMixerTrack>(Child3);
Selector.AddTrack(MixerTrackWidget3->GetMixerTrack());
}
break;
}
}
break;
}
}
}
}
else
{
Selector.AddTrack(InMixerTrack);
EffectList->SetMixerTrack(InMixerTrack);
}
}
void SMixer::OnMixerTrackSelected(FMixerTrack* InMixerTrack)
{
ForeachMixerTrackWidget([&, this](TSharedRef<SMixerTrack> MixerTrackWidget)
{
if (MixerTrackWidget->GetMixerTrack() == InMixerTrack)
{
MixerTrackWidget->SetSelected(true);
return false;
}
return true;
});
}
void SMixer::OnMixerTrackDeselected(FMixerTrack* InMixerTrack)
{
ForeachMixerTrackWidget([&, this](TSharedRef<SMixerTrack> MixerTrackWidget)
{
if (MixerTrackWidget->GetMixerTrack() == InMixerTrack)
{
MixerTrackWidget->SetSelected(false);
return false;
}
return true;
});
}
void SMixer::ForeachMixerTrackWidget(TFunction<bool(TSharedRef<SMixerTrack>)> InFunction)
{
const TSharedPtr<SScrollPanel> ScrollPanel = ListView->GetScrollPanel();
FChildren* Children = ScrollPanel->GetChildren();
for (int32 i = 0; i < Children->Num(); i++)
{
TSharedRef<SWidget> Child = Children->GetChildAt(i);
const TSharedRef<SMixerTrack> MixerTrackWidget = StaticCastSharedRef<SMixerTrack>(Child);
if (!InFunction(MixerTrackWidget))
break;
}
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
#undef LOCTEXT_NAMESPACE