125 lines
3.6 KiB
C++
125 lines
3.6 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
|
|
#include "ChannelRackMidiThumbnail.h"
|
|
|
|
#include "SImage.h"
|
|
#include "SInvalidationPanel.h"
|
|
#include "SlateApplication.h"
|
|
#include "SlateOptMacros.h"
|
|
#include "SScrollBox.h"
|
|
#include "SViewport.h"
|
|
#include "Midi/MidiMessageSequence.h"
|
|
#include "Singleton/MidiSequencer.h"
|
|
#include "UI/Widget/MainWindow.h"
|
|
#include "UI/Widget/SUpdatableImage.h"
|
|
#include "UI/Widget/Thumbnail.h"
|
|
#include "UI/Widget/WindowManager.h"
|
|
#include "UI/Widget/PianoRoll/SPianoRoll.h"
|
|
|
|
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
|
|
|
SChannelRackMidiThumbnail::~SChannelRackMidiThumbnail()
|
|
{
|
|
SetPattern(nullptr);
|
|
}
|
|
|
|
void SChannelRackMidiThumbnail::SetPattern(FMidiPattern* InPattern)
|
|
{
|
|
if (CurrentPattern)
|
|
{
|
|
CurrentPattern->OnChanged.RemoveAll(this);
|
|
CurrentPattern->OnPlay.RemoveAll(this);
|
|
}
|
|
if (!InPattern)
|
|
return;
|
|
CurrentPattern = InPattern;
|
|
CurrentPattern->OnChanged_MainThread.AddRaw(this, &SChannelRackMidiThumbnail::OnChanged);
|
|
CurrentPattern->OnPlay.AddRaw(this, &SChannelRackMidiThumbnail::OnPatternPlay);
|
|
OnChanged(PluginHost, &InPattern->GetSequence(PluginHost));
|
|
}
|
|
|
|
void SChannelRackMidiThumbnail::Construct(const FArguments& InArgs, FPluginHost* InPluginHost)
|
|
{
|
|
PluginHost = InPluginHost;
|
|
SetPattern(InArgs._Pattern);
|
|
|
|
ChildSlot
|
|
[
|
|
SNew(SInvalidationPanel)
|
|
[
|
|
SAssignNew(UpdatableImage, SUpdatableImage)
|
|
.OnPostResize(this, &SChannelRackMidiThumbnail::UpdateMidiThumbnail)
|
|
.UpdateInterval(0)
|
|
]
|
|
];
|
|
|
|
if (InArgs._Pattern)
|
|
OnChanged(PluginHost, &InArgs._Pattern->GetSequence(InPluginHost));
|
|
}
|
|
|
|
FReply SChannelRackMidiThumbnail::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
|
{
|
|
if (!CurrentPattern)
|
|
return FReply::Unhandled();
|
|
FMidiMessageSequence* MidiSequence = &CurrentPattern->GetSequence(PluginHost);
|
|
TSharedPtr<SPianoRoll> PianoRoll = SNew(SPianoRoll, MidiSequence, PluginHost);
|
|
|
|
|
|
FWindowManager::Get().GetMainWindow()->CreateChildWindow(
|
|
FVector2D(100, 100),
|
|
TEXT(""),
|
|
PianoRoll.ToSharedRef()
|
|
);
|
|
PianoRoll->InitScrollBar();
|
|
return FReply::Unhandled();
|
|
}
|
|
|
|
int32 SChannelRackMidiThumbnail::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
|
|
{
|
|
LayerId = SCompoundWidget::OnPaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);
|
|
if (CurrentPattern)
|
|
{
|
|
const double EndTime = CurrentPattern->GetLength();
|
|
const double CurrentPercent = LastPatternPos / EndTime * (double)AllottedGeometry.Size.X;
|
|
TArray<FVector2f> Points;
|
|
Points.Add(FVector2f(CurrentPercent, 0));
|
|
Points.Add(FVector2f(CurrentPercent, AllottedGeometry.Size.Y));
|
|
FSlateDrawElement::MakeLines(
|
|
OutDrawElements,
|
|
++LayerId,
|
|
AllottedGeometry.ToPaintGeometry(),
|
|
Points,
|
|
ESlateDrawEffect::None,
|
|
FLinearColor::Red,
|
|
true,
|
|
1.f
|
|
);
|
|
}
|
|
return LayerId;
|
|
}
|
|
|
|
void SChannelRackMidiThumbnail::OnChanged(FPluginHost* Host, FMidiMessageSequence* Changed)
|
|
{
|
|
if (Host != PluginHost)
|
|
return;
|
|
UpdatableImage->NeedRedraw();
|
|
}
|
|
|
|
void SChannelRackMidiThumbnail::OnPatternPlay(FPatternInstance* PatternInstance, AudioFrame PatternTick, uint32 Length)
|
|
{
|
|
LastPatternPos = PatternTick;
|
|
}
|
|
|
|
void SChannelRackMidiThumbnail::UpdateMidiThumbnail(FImageData& ImageData)
|
|
{
|
|
if (!CurrentPattern)
|
|
return;
|
|
const FMidiMessageSequence* MidiSequence = &CurrentPattern->GetSequence(PluginHost);
|
|
|
|
ImageData.ClearColor(FColor::Black);
|
|
Thumbnail::GenerateMidiThumbnail(MidiSequence, ImageData);
|
|
}
|
|
|
|
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|