162 lines
4.1 KiB
C++
162 lines
4.1 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
|
|
#include "SPatternInstance.h"
|
|
|
|
#include "SButton.h"
|
|
#include "SInvalidationPanel.h"
|
|
#include "SlateOptMacros.h"
|
|
#include "STextBlock.h"
|
|
#include "SViewport.h"
|
|
#include "Pattern/PatternInstance.h"
|
|
#include "Render/UpdatableTexture.h"
|
|
#include "UI/Widget/SUpdatableTexture.h"
|
|
#include "Widgets/SBoxPanel.h"
|
|
|
|
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
|
|
|
void SPatternInstance::Construct(const FArguments& InArgs)
|
|
{
|
|
PatternInstance = InArgs._PatternInstance;
|
|
FrameToPixel = InArgs._FrameToPixel;
|
|
SnapFrame = InArgs._SnapFrame;
|
|
FrameViewRange = InArgs._FrameViewRange;
|
|
|
|
ChildSlot
|
|
[
|
|
SNew(SOverlay)
|
|
+SOverlay::Slot()
|
|
[
|
|
SNew(SBorder)
|
|
.BorderBackgroundColor(FLinearColor(0, 0, 0, 0.3f))
|
|
]
|
|
|
|
+SOverlay::Slot()
|
|
[
|
|
SNew(SVerticalBox)
|
|
+SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
[
|
|
SNew(SHorizontalBox)
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
[
|
|
SNew(SButton)
|
|
.Text(FText::FromString("X"))
|
|
.OnClicked(this, &SPatternInstance::OpenPatternMenu)
|
|
]
|
|
+SHorizontalBox::Slot()
|
|
.FillWidth(1.f)
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(FText::FromString(PatternInstance->GetOwner()->Name))
|
|
.OverflowPolicy(ETextOverflowPolicy::Ellipsis)
|
|
.Justification(ETextJustify::Left)
|
|
]
|
|
]
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(1.f)
|
|
[
|
|
GetViewWidget()
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
FReply SPatternInstance::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
|
{
|
|
if (ResizeDirection != ResizeDir::None)
|
|
{
|
|
FPatternSelector::Get().SelectPatternInstance(PatternInstance);
|
|
const TRange<AudioFrame>& Range = PatternInstance->TimeRange;
|
|
BeginPatternStart = Range.GetLowerBoundValue();
|
|
BeginPatternEnd = Range.GetUpperBoundValue();
|
|
MouseDownPos = MouseEvent.GetScreenSpacePosition();
|
|
BeginPatternPos = PatternInstance->Pos;
|
|
return FReply::Handled().CaptureMouse(AsShared());
|
|
}
|
|
return FReply::Unhandled();
|
|
}
|
|
|
|
FReply SPatternInstance::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
|
{
|
|
if (ResizeDirection != ResizeDir::None)
|
|
{
|
|
PatternInstance->RequestEndSetting();
|
|
return FReply::Handled().ReleaseMouseCapture();
|
|
}
|
|
return FReply::Unhandled();
|
|
}
|
|
|
|
FReply SPatternInstance::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
|
{
|
|
const FVector2f LocalMousePos = MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition());
|
|
|
|
if (MouseEvent.IsMouseButtonDown(EKeys::LeftMouseButton))
|
|
{
|
|
const float MouseDelta = (MouseEvent.GetScreenSpacePosition().X - MouseDownPos.X) / MyGeometry.Scale;
|
|
const float Scaler = FrameToPixel.Get();
|
|
const bool NoSnap = MouseEvent.GetModifierKeys().IsAltDown();
|
|
double Delta = MouseDelta / Scaler;
|
|
if (!NoSnap)
|
|
Delta = FMath::GridSnap(Delta, SnapFrame.Get());
|
|
|
|
switch (ResizeDirection)
|
|
{
|
|
case ResizeDir::None: break;
|
|
case ResizeDir::Left:
|
|
{
|
|
AudioFrame NewRangeStart = BeginPatternStart + Delta;
|
|
AudioFrame NewPos = BeginPatternPos + Delta;
|
|
if (NewRangeStart.Pos < 0)
|
|
{
|
|
NewPos -= NewRangeStart;
|
|
NewRangeStart = 0;
|
|
}
|
|
if (NewPos.Pos < 0)
|
|
{
|
|
NewRangeStart -= NewPos;
|
|
NewPos = 0;
|
|
}
|
|
PatternInstance->TimeRange.SetLowerBoundValue(NewRangeStart);
|
|
PatternInstance->SetMidiPos(NewPos.Ticks());
|
|
return FReply::Handled();
|
|
}
|
|
case ResizeDir::Right:
|
|
{
|
|
const AudioFrame NewRangeEnd = FMath::Max<AudioFrame>(0, BeginPatternEnd + Delta);
|
|
PatternInstance->TimeRange.SetUpperBoundValue(NewRangeEnd);
|
|
return FReply::Handled();
|
|
}
|
|
default: ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (LocalMousePos.X <= ResizeHandleSize)
|
|
{
|
|
ResizeDirection = ResizeDir::Left;
|
|
}
|
|
else if (LocalMousePos.X >= MyGeometry.GetLocalSize().X - ResizeHandleSize)
|
|
{
|
|
ResizeDirection = ResizeDir::Right;
|
|
}
|
|
else
|
|
{
|
|
ResizeDirection = ResizeDir::None;
|
|
}
|
|
switch (ResizeDirection)
|
|
{
|
|
case ResizeDir::None: SetCursor(EMouseCursor::Default); break;
|
|
case ResizeDir::Left:
|
|
case ResizeDir::Right: SetCursor(EMouseCursor::ResizeLeftRight); break;
|
|
default: ;
|
|
}
|
|
}
|
|
|
|
return FReply::Unhandled();
|
|
}
|
|
|
|
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|