// 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 MixerTrackWidget) { if (MixerTrackWidget->GetMixerTrack() == MixerTrack) { ListView->RemoveSlot(MixerTrackWidget); return false; } return true; }); } void SMixer::OnMixerTrackClicked(FMixerTrack* InMixerTrack) { Selector.UnselectAll(); if (bShiftDown) { const TArray& Selected = Selector.GetSelectedTracks(); if (Selected.Num() > 0) { const TSharedPtr ScrollPanel = ListView->GetScrollPanel(); FChildren* Children = ScrollPanel->GetChildren(); for (int32 i = 0; i < Children->Num(); i++) { TSharedRef Child = Children->GetChildAt(i); const TSharedRef MixerTrackWidget = StaticCastSharedRef(Child); if (MixerTrackWidget->GetMixerTrack() == Selected[0]) { int32 StartIndex = i; for (int32 j = 0; j < Children->Num(); j++) { TSharedRef Child2 = Children->GetChildAt(j); const TSharedRef MixerTrackWidget2 = StaticCastSharedRef(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 Child3 = Children->GetChildAt(k); const TSharedRef MixerTrackWidget3 = StaticCastSharedRef(Child3); Selector.AddTrack(MixerTrackWidget3->GetMixerTrack()); } break; } } break; } } } } else { Selector.AddTrack(InMixerTrack); EffectList->SetMixerTrack(InMixerTrack); } } void SMixer::OnMixerTrackSelected(FMixerTrack* InMixerTrack) { ForeachMixerTrackWidget([&, this](TSharedRef MixerTrackWidget) { if (MixerTrackWidget->GetMixerTrack() == InMixerTrack) { MixerTrackWidget->SetSelected(true); return false; } return true; }); } void SMixer::OnMixerTrackDeselected(FMixerTrack* InMixerTrack) { ForeachMixerTrackWidget([&, this](TSharedRef MixerTrackWidget) { if (MixerTrackWidget->GetMixerTrack() == InMixerTrack) { MixerTrackWidget->SetSelected(false); return false; } return true; }); } void SMixer::ForeachMixerTrackWidget(TFunction)> InFunction) { const TSharedPtr ScrollPanel = ListView->GetScrollPanel(); FChildren* Children = ScrollPanel->GetChildren(); for (int32 i = 0; i < Children->Num(); i++) { TSharedRef Child = Children->GetChildAt(i); const TSharedRef MixerTrackWidget = StaticCastSharedRef(Child); if (!InFunction(MixerTrackWidget)) break; } } END_SLATE_FUNCTION_BUILD_OPTIMIZATION #undef LOCTEXT_NAMESPACE